Security - marco1475/linux-htpc GitHub Wiki

iptables

  1. Install the iptables package:

     pacman -S iptables
    
  2. Make sure you create the /etc/iptables/iptables.rules file with an empty configuration:

     iptables-save > /etc/iptables/iptables.rules
    
  3. Run the following commands:

     iptables -N TCP
     iptables -N UDP
     
     iptables -P FORWARD DROP
     
     iptables -P OUTPUT ACCEPT
     
     iptables -P INPUT DROP
     iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
     iptables -A INPUT -i lo -j ACCEPT
     iptables -A INPUT -m conntrack --ctstate INVALID -j DROP
     iptables -A INPUT -p icmp --icmp-type 8 -m conntrack --ctstate NEW -j ACCEPT
     iptables -A INPUT -p udp -m conntrack --ctstate NEW -j UDP
     iptables -A INPUT -p tcp --syn -m conntrack --ctstate NEW -j TCP
     iptables -A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable
     iptables -A INPUT -p tcp -j REJECT --reject-with tcp-reset
     iptables -A INPUT -j REJECT --reject-with icmp-proto-unreachable
    
  4. Save the general rules to the configuration file:

     iptables-save > /etc/iptables/iptables.rules
    
  5. Add port-specific rules to the configuration, in the order of their frequency:

     iptables -A TCP -p tcp --dport 80 -j ACCEPT    # HTTP
     iptables -A TCP -p tcp --dport 443 -j ACCEPT   # HTTPS
     iptables -A TCP -p tcp --dport 6622 -j ACCEPT  # SSH
     iptables -A TCP -p tcp --dport 6621 -j ACCEPT  # FTP
     iptables -A TCP -p tcp --dport 65534 -j ACCEPT # MPD Control
     iptables -A TCP -p tcp --dport 65535 -j ACCEPT # MPD Stream
    
  6. Save the configuration to the configuration file:

     iptables-save > /etc/iptables/iptables.rules
    
  7. Prevent SYN scans:

     iptables -I TCP -p tcp -m recent --update --seconds 60 --name TCP-PORTSCAN -j REJECT --reject-with tcp-reset
     iptables -D INPUT -p tcp -j REJECT --reject-with tcp-reset    # Delete the old rule
     iptables -A INPUT -p tcp -m recent --set --name TCP-PORTSCAN -j REJECT --reject-with tcp-reset
    
  8. Prevent UDP scans:

     iptables -I UDP -p udp -m recent --update --seconds 60 --name UDP-PORTSCAN -j REJECT --reject-with icmp-port-unreachable
     iptables -D INPUT -p udp -j REJECT --reject-with icmp-port-unreachable    # Delete the old rule
     iptables -A INPUT -p udp -m recent --set --name UDP-PORTSCAN -j REJECT --reject-with icmp-port-unreachable
    
  9. Ensure the final default rule is the last rule in the configuration:

     iptables -D INPUT -j REJECT --reject-with icmp-proto-unreachable
     iptables -A INPUT -j REJECT --reject-with icmp-proto-unreachable
    
  10. Save the configuration to the configuration file:

    iptables-save > /etc/iptables/iptables.rules
    
  11. Start the iptables service:

    systemctl start iptables.service
    
  12. Check on the status of the service (systemctl status iptables.service) and if it is running correctly, ensure it starts on boot:

    systemctl enable iptables.service
    

Fail2Ban

  1. Install the fail2ban package:

     pacman -S fail2ban
    
  2. Harden the fail2ban service:

    1. Create a drop-in configuration file for the fail2ban service:

       systemctl edit fail2ban
      
    2. In the text editor that opened, add the following lines:

       [Service]
       CapabilityBoundingSet=CAP_DAC_READ_SEARCH CAP_NET_ADMIN CAP_NET_RAW
       ReadOnlyDirectories=/
       ReadWriteDirectories=/var/run/fail2ban /var/lib/fail2ban /tmp /var/log/fail2ban.log
      
  3. Make sure to reload the systemd daemon to make it aware of the drop-in configuration file:

     systemctl daemon-reload
    
  4. Create a new /etc/fail2ban/jail.d/ssh-iptables.conf local jail file:

     [DEFAULT]
     ignoreip = 127.0.0.1/8 192.168.1.3/24
     bantime = 600
     
     [sshd]
     enabled = true
     filter = sshd
     action = iptables[name=SSH, port=6622, protocol=tcp]
              sendmail-whois[name=SSH, [email protected], [email protected]]
     backend = systemd
     maxretry = 5
    
    • By default %(sshd_backend)s is set to auto, which will try to use pyinotify, gamin, and polling, but not systemd.
    • When using the systemd backend, specifying logpath for a jail is not valid.
  5. Start the fail2ban service:

     systemctl start fail2ban.service
    
  6. Check on the status of the service (systemctl status fail2ban.service) and if it is running correctly, ensure it starts on boot:

     systemctl enable fail2ban.service
    

Secure Shell

Creating Keys

  1. Create a public-private key pair:

     ssh-keygen -b 4096
    
    • Use RSA, because DSA has been deprecated due to security concerns, ECDSA may also have security flaws, and Ed25519 isn't widely established.
    • Use 4096 bit key size, because NSA Fact Sheet Suite B Cryptography suggests a minimum 3072-bit modulus for RSA.
    • The private SSH key should have permissions 700, so it's readable by only the user.
    • On Windows, use PuTTYgen to convert the id_rsa key to a .ppk key usable with PuTTY.
  2. Copy the public key (id_rsa.pub) to the remote machine and add it to that machine's user's ~/.ssh/authorized_keys file.

     ~/.ssh/authorized_keys << id_rsa.pub
    
  3. Copy the private key (id_rsa) to the local machine's ~/.ssh directory and use it connect to the remote machine:

     ssh -p <port> <user>@<remote-machine>
    

Adding Two-factor Authentication

  1. Install the libpam-google-authenticator package from the AUR.

    • Run the following after the installation has succeeded:

        libtool --finish /usr/lib/security
      
  2. Install the qrencode package:

     pacman -S qrencode
    
  3. Edit /etc/ssh/sshd_config:

     ChallengeResponseAuthentication yes
     AuthenticationMethods publickey,keyboard-interactive:pam
    
  4. Edit /etc/pam.d/sshd:

    1. Comment out the following line:

       #auth include system-remote-login
      
    2. Add the following line right after the just commented-out line:

       auth required pam_google_authenticator.so no_increment_hotp
      
  5. Generate the secret key file in the user's home directory:

     google-authenticator
    
    • Add the account to your Google Authenticator mobile app by scanning the QR code shown.
  6. Restart the sshd.socket service:

     systemctl restart sshd.socket
    

File Transfer

  • The two-factor authentication (key-pair + Google Authenticator) makes SFTP connections using (S)FTP clients more complicated:
    • Using "interactive" (or "prompt" or "keyboard") authentication modes won't work, because the first authentication level is the key pair.
    • However, using the "key' authentication mode will fail, because it doesn't answer the server's second, interactive prompt for the Google Authenticator passcode.
    • The solution is to use an SSH authentication agent (e.g. Pageant) to provide the key automatically and then select the "interactive" authentication mode, which will ask you for the Google Authenticator passcode.

Pretty Good Privacy

About

PGP keys have three parts:

  1. a single master key,
  2. one or more subkeys, and
  3. one or more UserIDs.

The master key's private half proves ownership of the PGP key and is used to add/remove subkeys and sign/certify other people's keys. The master key does not need to be present for every day signing and encryption. It should be kept offline and only used to add or revoke subkeys or certify another person's PGP key.

Subkeys can be used to sign data, encrypt data and/or for authentication. The lifetime and purpose (sign, encrypt, authenticate) of a subkey is controlled by the master key. Subkeys can be added or removed from the PGP key only by using the master key.

UserIDs are used to identify the owner of the PGP key. The UserID contains the name and e-mail address of the person who owns the PGP key. UserIDs are added to a PGP key using the master key.

Since subkeys can be used for encryption/decryption and signing without the presence of the master key, the daily-used PGP key should not contain the master key. The master key controls the validity and lifetime of subkeys, so should the daily-used PGP key be stolen or compromised, the safely-stored master key can be used to revoke the compromised subkeys and create new ones. This avoids the need to re-generate the whole PGP key.

Methodology

You want to generate the following keys:

  1. Master key:
    • Used only for certifying new subkeys and other people's PGP keys, i.e. not daily use.
    • Generated by GPG with a 1 year validity.
    • Kept on an air-grapped, offline, encrypted USB drive.
  2. Encryption subkey:
    • Used for encrypting and decrypting data.
    • Generated by GPG with a 1 year validity.
    • The same copy is copied to all Yubikeys.
  3. Signing subkey:
    • Used for signing data.
    • Generated on each Yubikey with a 1 year validity.
    • The private key never leaves the Yubikey and it is impossible to extract it.
  4. Authentication subkey:
    • Used for authentication (SSH logins).
    • Generated on each Yubikey with a 1 year validity.
    • The private key never leaves the Yubikey and it is impossible to extract it.

PGP keys generated on the YubiKey cannot be copied off of the device, which makes them YubiKey-specific. The encryption subkey should be locally-generated and copied to each Yubikey so other people have only a single encryption key to target for you. The signing and authentication keys should be generated on each Yubikey and be Yubikey-specific.

A gpg-like output of the desired state (with a main and a backup Yubikey):

sec  rsa4096/<MASTER_KEY>
     created: <date>  expires: <date>  usage: C   
     trust: ultimate      validity: ultimate
sub  rsa2048/<ENCRYPTION_SUBKEY>
     created: <date>  expires: <date>  usage: E   
     card-no: 1234 56789001
     card-no: 1234 56789002
sub  rsa2048/<SIGNING_SUBKEY1>
     created: <date>  expires: <date>  usage: S   
     card-no: 1234 56789001
sub  rsa2048/<AUTHENTICATION_SUBKEY1>
     created: <date>  expires: <date>  usage: A   
     card-no: 1234 56789001
sub  rsa2048/<SIGNING_SUBKEY2>
     created: <date>  expires: <date>  usage: S   
     card-no: 1234 56789002
sub  rsa2048/<AUTHENTICATION_SUBKEY2>
     created: <date>  expires: <date>  usage: A   
     card-no: 1234 56789002
[ultimate] (1). <UserID>

Ideally you want to create your master key and all subkeys on an offline, air-gapped machine and generate them directly onto the encrypted USB drive that will be used as the master key backup.

The master key backup will contain the master key's private (secret) key, its revocation certificate, the encryption subkey's private (secret) key, and the two private RSA keys (one for the master key and one for the encryption key) that are automatically generated. These private keys should never leave the encrypted USB drive.

The signing and authentication private keys are generated on the Yubikeys and cannot be extracted.

All these private keys share the same public key (the master key's). The public key should be distributed to a location where others can find it. This location should be embedded in the PGP key itself so others will know where to get the key with the most up-to-date signatures, subkeys, and revocations.

Preparing the Environment

  1. Boot into a LiveCD environment (in this case, Ubuntu 17.04 (Zesty Zapus)).

  2. Connect to the internet.

  3. Install the required software:

    1. Navigate to Settings -> Software and Updates and ensure that the following checkboxes are enabled:

      • Canonical-supported free and open-source software (main)
      • Community-maintained free and open-source software (universe)
      • Proprietary drivers for devices (restricted)
      • Software restricted by copyright or legal issues (multiverse)
    2. Open the Terminal and install the necessary software:

       sudo apt-get install scdaemon opensc pcsc-tools
      
    3. Download the ykpersonalize tool.

  4. Disconnect from the internet and disable networking altogether.

  5. Prepare each Yubikey:

    1. Plug in the Yubikey.

    2. Set the eject flag to 82 to enable OTP and CCID compatibility:

       ykpersonalize -m86
      
      • This can also be achieved using the GUI Yubikey NEO Manager, available for Windows and macOS.
    3. Start the gpg utility in smartcard-editing mode:

       gpg --card-edit
      
      • In the print out take note of the Signature PIN ....: field.
      • The following commands should be entered in the gpg/card> prompt.
    4. Type admin to enable administrator commands.

    5. Change the user and admin passwords:

      The default administrator PIN is 12345678. The default user PIN is 123456.

      1. Type passwd and hit Enter.
      2. Select option 1 - change PIN to change the user PIN.
      3. Select option 3 - change Admin PIN to change the administrator PIN.
      4. Type q and hit Enter to exit passwd mode.
    6. If the Signature PIN ....: is set to not forced, force is on by typing forcesig and hitting Enter.

    7. Set the card information by using the name, sex, and lang commands.

    8. Type quit to exit.

    9. Unplug the Yubikey.

  6. Encrypt the USB drive where you wish to store the master key.

    1. Plug in the USB drive.

    2. Determine the label of the USB drive:

       lsblk
      
      • Be aware that the LiveCD installation is running off of a different USB drive; do not confuse them!
    3. Start the fdisk partitioning utility:

       sudo fdisk /dev/sdX
      
      • If there are any partitions present remove them by creating a new, empty GUID partition table (o) and writing it to disk (w).
    4. Create a new partition.

      1. Press n and hit Enter to create a new partition.
      2. Press Enter to create a primary partition.
      3. Press Enter to accept the default partition number (in this case 1).
      4. Press Enter again to accept the default first sector (in this case 2048).
      5. Press Enter again to accept the default last sector.
      6. Press w to write the partition table to disk.
    5. Create a LUKS container on the new partition:

       sudo cryptsetup luksFormat /dev/sdX1
      
    6. Open the LUKS container:

       sudo cryptsetup luksOpen /dev/sdX1 encrypted-backup
      
    7. Create a filesystem within the LUKS container:

       sudo mkfs.ext3 /dev/mapper/encrypted-backup -L BACKUP
      
    8. Close the LUKS container:

       sudo cryptsetup luksClose encrypted-backup
      
    9. Unplug the USB drive.

  7. Plug in the USB drive where you wish to store the master key.

    • The LiveCD environment should recognize the encrypted partition, ask you for the password, and automatically mount it under /media/ubuntu/BACKUP.
  8. Ensure that the generated keys will be stored on the encrypted USB drive:

     mkdir /media/ubuntu/BACKUP/.gnupg
     ln -s /media/ubuntu/BACKUP/.gnupg .gnupg
     sudo chown -R $(whoami):$(whoami) ~/.gnupg
     sudo chmod 700 ~/.gnupg
    
  9. Set GnuPG to prefer strong hash and encryption algorithms:

    echo "cert-digest-algo SHA512" >> .gnupg/gpg.conf
    echo "default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed" >> .gnupg/gpg.conf
    

Generate the Master Key

  1. Start the gpg utility in expert mode:

     gpg --expert --gen-key
    
  2. Select option (8) RSA (set your own capabilities).

  3. Using the toggles s, e, and a change the Current allowed actions to just Certify and quit (q) when done.

  4. Specify a keysize of 4096.

    • The individual subkeys can have a max. keysize of 2048 because of Yubikey restrictions, but the master key can be of any size.
  5. Specify a 1-year validity period (1y).

  6. Construct a user ID based on your name and e-mail address.

  7. Enter a passphrase.

  8. Generate a lot of entropy.

  9. The master key should like something like this (with MASTER_KEY being the key's identifier):

     pub   rsa4096 <date> [C] [expires: <date>]
           <MASTER_KEY>
     uid   <UserID>
    

Generate a Revocation Certificate

  1. Generate a revocation certificate for the master key:

     gpg --gen-revoke <MASTER_KEY> > /media/ubuntu/BACKUP/<MASTER_KEY>-revocation-certificate.asc
    
  2. Specify a reason for revocation (1 = Key has been compromised is as good as any).

Generate the Encryption Key

  1. Edit the master key using gpg:

     gpg --edit-key <MASTER_KEY>
    
    • The last 16 digits of the MASTER_KEY identifier are usually enough to identify the key in question.
  2. Add a new key:

     gpg> addkey
    
  3. Select option (6) RSA (encrypt only).

  4. Specify a keysize of 2048.

    • Any subkey that will be stored on a Yubikey can have a max. keysize of 2048 because of Yubikey restrictions.
  5. Specify a 1-year validity period (1y).

  6. Generate a lot of entropy.

  7. The master key should like something like this (with MASTER_KEY and ENCRYPTION_KEY being the keys' identifiers):

     sec  rsa4096/<MASTER_KEY>
          created: <date>  expires: <date>  usage: C   
          trust: ultimate      validity: ultimate
     ssb  rsa2048/<ENCRYPTION_KEY>
          created: <date>  expires: <date>  usage: E   
     [ultimate] (1). <UserID>
    
  8. Save the master key:

     gpg> save
    

Make a Backup of Secret Keys

Adding keys to smartcards (e.g. Yubikeys) is a destructive action, i.e. the secret key will be removed from the local keychain. Make sure you have backed up the secret keys so you can re-import them when initializing a new Yubikey.

  1. Export the master and encryption secret keys to a file on the encrypted USB drive:

     gpg --export-secret-key <MASTER_KEY> > /media/ubuntu/BACKUP/<MASTER_KEY>-<date>-<ENCRYPTION_KEY>-secret.pgp
    

For Each Yubikey

  1. It is good practice to re-import the master and encryption keys from the backup before initializing each Yubikey to ensure that both keys are in the keychain and that the backup is working:

     gpg --delete-secret-key <MASTER_KEY>
     gpg --import < /media/USB/<MASTER_KEY>-<date>-<ENCRYPTION_KEY>-secret.pgp
    
  2. Plug in the Yubikey.

  3. Edit the newly-imported master key using gpg:

     gpg --edit-key <MASTER_KEY>
    
  4. Generate the Yubikey-specific signing subkey:

    1. Add a cardkey:

       gpg> addcardkey
      
    2. Select (1) Signature key.

    3. Enter the admin and user PINs for the Yubikey.

      • By default the user PIN is 123456 and the admin PIN is 12345678.
    4. Specify a 1-year validity period (1y).

    5. The Yubikey will flash for a while and you will be prompted for the master key password.

    6. The master key should like something like this (with MASTER_KEY, ENCRYPTION_KEY, and SIGNING_KEY being the keys' identifiers):

       sec  rsa4096/<MASTER_KEY>
            created: <date>  expires: <date>  usage: C   
            trust: ultimate      validity: ultimate
       ssb  rsa2048/<ENCRYPTION_KEY>
            created: <date>  expires: <date>  usage: E   
       ssb  rsa2048/<SIGNING_KEY>
            created: <date>  expires: <date>  usage: S   
            card-no: 1234 56789001
       [ultimate] (1). <UserID>
      
  5. Generate the Yubikey-specific authentication subkey:

    1. Add a cardkey:

       gpg> addcardkey
      
    2. Select (3) Authentication key.

    3. Enter the admin and user PINs for the Yubikey.

      • By default the user PIN is 123456 and the admin PIN is 12345678.
    4. Specify a 1-year validity period (1y).

    5. The Yubikey will flash for a while and you will be prompted for the master key password.

    6. The master key should like something like this (with MASTER_KEY, ENCRYPTION_KEY, SIGNING_KEY, and AUTHENTICATION_KEY being the keys' identifiers):

       sec  rsa4096/<MASTER_KEY>
            created: <date>  expires: <date>  usage: C   
            trust: ultimate      validity: ultimate
       ssb  rsa2048/<ENCRYPTION_KEY>
            created: <date>  expires: <date>  usage: E   
       ssb  rsa2048/<SIGNING_KEY>
            created: <date>  expires: <date>  usage: S   
            card-no: 1234 56789001
       ssb  rsa2048/<AUTHENTICATION_KEY>
            created: <date>  expires: <date>  usage: A   
            card-no: 1234 56789001
       [ultimate] (1). <UserID>
      
  6. Move the locally-generated encryption subkey to the Yubikey:

    • Beware that this action will remove the encryption key from the local keychain. Make sure you have a backup that you can re-import for any subsequent Yubikeys!
    1. Use toggle and key to select the encryption subkey:

       gpg> toggle
       gpg> key 1
      
      • You should see a * next to the encryption key, i.e.: ssb* rsa2048/<ENCRYPTION_KEY>
    2. Using keytocard move the encryption subkey from the keyring to the Yubikey's (2) Encryption key slot:

       gpg> keytocard
      
    3. The Yubikey will flash and you will be prompted for the master key password.

  7. Save the master key:

     gpg> save
    
  8. The master key, stored on the encrypted USB drive, now has no encryption, signing, or authentication subkeys, because all of them have been moved to the Yubikey.

Save and Distribute the Master Public Key

  1. Start gpg utility and edit the master key:

     gpg --edit-key <MASTER_KEY>
    
  2. Use the keyserver command to enter the URL of the server where your public key can be found, e.g. https://marek.vojtko.com/static/<MASTER_KEY>.asc

  3. Verify that everything is correct using the showpref command.

  4. Save the master key by typing save.

  5. Backup the public key:

     gpg --armor --export <MASTER_KEY> > /media/ubuntu/BACKUP/<MASTER_KEY>.asc
    
  6. Upload the public key to the keyserver:

     scp /media/ubuntu/BACKUP/<MASTER_KEY>.asc <user>@<server>:public_html/static/<MASTER_KEY>.asc
     gpg --keyserver http://pgp.mit.edu --send-key <MASTER_KEY>
    
  7. Add the public key URL to each Yubikey:

    1. Start the gpg utility in smartcard-editing mode:

       gpg --card-edit
      
      • The following commands should be entered in the gpg/card> prompt.
    2. Type admin to enable administrator commands.

    3. Type url to enter the URL where the public key can be retrieved.

    4. Type quit to exit.

  8. Generate the SSH public key from the master key-pair's public key (TODO: I think this applies to the currently plugged-in Yubikey only):

     ssh-add -L > /media/ubuntu/BACKUP/<MASTER_KEY>.pub
    
    • Add this public key to a server's .ssh/authorized_keys file to connect to it using the Yubikey's authentication key.
    • TODO: Getting the SSH public keys from each individual Yubikey by following the "client" setup on Linux:
      1. Insert Yubikey.
      2. Import public key into a brand-new keychain.
      3. Do gpg --card-status to populate the secret keys.
      4. Set the master key's trust.
      5. Set up .gpg-agent.conf.
      6. Replace ssh-agent with gpg-agent.
      7. Only then will you be able to call ssh-add -l to see the currently plugged-in Yubikey's private SSH key and, conversely, call ssh-add -L to get the key's public SSH key that you can add to your server's .ssh/authorized_keys file.
      8. For some reason the public SSH key generated from the master key does not allow authentication with the Yubikey subkeys.
  9. Remove the .gnupg symlink:

     rm .gnupg
    
  10. Eject the encrypted USB drive (in the UI) and store it in a safe, air-gapped location.

Setting Up a Client

Windows

  1. Install GPG4Win, including GPA (GNU Privacy Assistant) and PuTTY (feel free to skip Kleopatra).

  2. Enable PuTTY support in GPG4Win using GPA:

    1. Navigate to Edit -> Backend Preferences.
    2. Under the Private Keys (GPG4Win 3.0 and newer) or GPG Agent (GPG4Win older than 3.0) tab, make sure enable-putty-support is checked.
    3. Restart the GPG agent.
  3. Import your public key to GPA.

  4. Ensure that no other smart card reader hardware or software is connected or running (e.g. eID).

    • You can verify that the Yubikey is recognized by opening GPA's card manager where you should see the Yubikey and its information.
  5. If you are using PuTTY, you can just connect via SSH and you should be prompted for the PIN.

  6. If you are using Cygwin, make sure that gpg is not installed, install ssh-pageant, and add the following to your ~/.bashrc file:

     # ssh-pageant
     eval $(/usr/bin/ssh-pageant -r -a "/tmp/.ssh-pageant-$USERNAME")
    
  7. If you reboot your machine, make sure to run GPA once to load the certificate into the GPG agent.

macOS

  1. Install GPGTools and log out and back in.

  2. Add the following to your ~/.bashrc:

     if [ -f "${HOME}/.gpg-agent-info" ]; then
         . "${HOME}/.gpg-agent-info"
         export GPG_AGENT_INFO
         export SSH_AUTH_SOCK
         export SSH_AGENT_PID
     fi
    
    • Note that a macOS Terminal is an interactive shell, which by default sources ~/.bash_profile, not ~/.bashrc.
    • See Common Tasks for how to make interactive shells source ~/.bashrc files.
  3. Add the following to your ~/.gnupg/gpg-agent.conf file:

     pinentry-program /usr/local/MacGPG2/libexec/pinentry-mac.app/Contents/MacOS/pinentry-mac
    

Linux

Common

  1. Insert the Yubikey.

  2. Import the master key-pair's public key.

    1. Either by manually importing from a file:

       gpg --import < <MASTER_KEY>.asc
      
    2. Or by fetching it from the URL encoded on the Yubikey:

       gpg --card-edit
       gpg/card> fetch
       gpg/card> quit
      
  3. Populate the local keyring with stub keys that point to the Yubikey:

     gpg --card-status
    
  4. The output should be similar to this:

     Reader ...........: Yubico Yubikey NEO OTP U2F CCID 00 00
     Application ID ...: <applicationID>
     Version ..........: 2.0
     Manufacturer .....: Yubico
     Serial number ....: <serialNumber>
     Name of cardholder: <name>
     Language prefs ...: <lang>
     Sex ..............: <sex>
     URL of public key : <url>
     Login data .......: [not set]
     Signature PIN ....: forced
     Key attributes ...: rsa2048 rsa2048 rsa2048
     Max. PIN lengths .: 127 127 127
     PIN retry counter : 3 3 3
     Signature counter : 1
     Signature key ....: 1234 5678 9ABC DEF0 0001  1234 5678 9ABC DEF0 0001
           created ....: <date> <time>
     Encryption key....: 1234 5678 9ABC DEF0 0002  1234 5678 9ABC DEF0 0002
           created ....: <date> <time>
     Authentication key: 1234 5678 9ABC DEF0 0003  1234 5678 9ABC DEF0 0003
           created ....: <date> <time>
     General key info..: sub  rsa2048/<SIGNING_KEY1> <date> <UserID>
     sec#  rsa4096/<MASTER_KEY>           created: <date>  expires: <date>
     ssb>  rsa2048/<ENCRYPTION_KEY>       created: <date>  expires: <date>
                                          card-no: 1234 56789001
     ssb>  rsa2048/<SIGNING_KEY1>         created: <date>  expires: <date>
                                          card-no: 1234 56789001
     ssb>  rsa2048/<AUTHENTICATION_KEY1>  created: <date>  expires: <date>
                                          card-no: 1234 56789001
     ssb>  rsa2048/<SIGNING_KEY2>         created: <date>  expires: <date>
                                          card-no: 1234 56789001
     ssb>  rsa2048/<AUTHENTICATION_KEY2>  created: <date>  expires: <date>
                                          card-no: 1234 56789001
    
    • The # next to the master key means that the private (secret) key is not present (because it is safely stored on a separate, encrypted USB drive).
  5. Set the local keyring to trust the master key.

    1. Start gpg utility and edit the master key:

       gpg --edit-key <MASTER_KEY>
      
    2. Use the trust command to select the trust level 5 ....

    3. Type quit and hit Enter to exit the gpg utility.

  6. Edit your ~/.gnupg/gpg-agent.conf file:

     enable-ssh-support
     default-cache-ttl 60
     max-cache-ttl 120
     write-env-file
     use-standard-socket
    
  7. Replace ssh-agent with gpg-agent:

     pkill ssh-agent ; pkill gpg-agent ; eval $(gpg-agent --daemon --enable-ssh-support --use-standard-socket --log-file ~/.gnupg/gpg-agent.log --write-env-file)
    
  8. If everything is set up correctly, you should see the following output when connecting via ssh (using the -v flag):

     debug1: Authentications that can continue: publickey,keyboard-interactive
     debug1: Next authentication method: publickey
     debug1: Offering RSA public key: cardno:123456789001
     debug1: Server accepts key: pkalg rsa-sha2-512 blen 279
    

Sources

[0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12]

⚠️ **GitHub.com Fallback** ⚠️