Skip to content

Instantly share code, notes, and snippets.

@hyper3xpl0iter
Created May 30, 2017 14:05
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hyper3xpl0iter/7ab3eeb283357e8facb119b98ef625d5 to your computer and use it in GitHub Desktop.
Save hyper3xpl0iter/7ab3eeb283357e8facb119b98ef625d5 to your computer and use it in GitHub Desktop.
A shell script to properly configure GNOME to play nice with a Yubikey. This script allows you to use your Yubikey for GPG and SSH while leaving passwords and PK11 for GNOME keyring (Ubuntu 15.04-17.10)
#!/bin/bash
################################################################################
#
# filename: yubikey-gnome.sh
# description: script to install and configure GNOME for Yubikey GPG/SSH
# author: Andre Mattie
# email: devel@introsec.ca
# GPG: 3E72 5D19 3C2D C443 7894 2DD7 4112 2434 0AF0 30EA
# bitcoin: 1ACWeGCHdxwT2qoKConZtaRnP4NYY1cyKy
# date: 05/30/2017
#
################################################################################
set -e
### GPG key ID (Change to match your keyID
# command to find key id: gpg -k --keyid-format 0xLONG
keyid="<ENTER-YOUR-KEY-ID>"
### Variables
gpgagent=~/.gnupg/gpg-agent.conf
gpgconf=~/.gnupg/gpg.conf
scdevent=~/.gnupg/scd-event
scconf=~/.gnupg/scdaemon.conf
udev50="/etc/udev/rules.d/50-security-key.rules"
udev70="/etc/udev/rules.d/70-u2f.rules"
udev90="/etc/udev/rules.d/90-yubikey.rules"
gnomegpg=~/.config/autostart/gnome-keyring-gpg.desktop
gnomepk=~/.config/autostart/gnome-keyring-pkcs11.desktop
gnomesec=~/.config/autostart/gnome-keyring-secrets.desktop
gnomessh=~/.config/autostart/gnome-keyring-ssh.desktop
gnomeagent=~/.config/autostart/gpg-agent.desktop
vividlist="/etc/apt/sources.list.d/vivid.list"
bashrc=~/.bashrc
bashpro=~/.bash_profile
### Add Ubuntu Vivid sources due to gnupg2 2.11 not working, need to use 2.0
function repo {
echo "Adding Ubuntu Vivid repository sources"
sudo echo "deb http://ca.archive.ubuntu.com/ubuntu/ vivid main restricted
deb http://ca.archive.ubuntu.com/ubuntu/ vivid-updates main restricted
deb http://ca.archive.ubuntu.com/ubuntu/ vivid universe
deb http://ca.archive.ubuntu.com/ubuntu/ vivid-updates universe
deb http://ca.archive.ubuntu.com/ubuntu/ vivid multiverse
deb http://ca.archive.ubuntu.com/ubuntu/ vivid-updates multiverse
deb http://ca.archive.ubuntu.com/ubuntu/ vivid-backports main restricted universe multiverse" | sudo tee $vividlist > /dev/null
return
}
### remove packages
function remove {
echo "Removing Ubuntu Xenial packages (gnupg2, gnupg-agent, scdaemon, pcscd)"
sudo apt-get purge --remove -y gnupg2 gnupg-agent scdaemon pcscd
sudo apt-get autoremove -y
return
}
### update package sources
function update {
echo "Updating sources"
sh -c 'apt-get update'
return
}
### install needed packages from vivid repository
function pkginst {
echo "Installing proper package versions from Ubuntu Vivid repository"
sudo apt-get install -y gnupg2=2.0.26-6ubuntu1 gnupg-agent=2.0.26-6ubuntu1 scdaemon=2.0.26-6ubuntu1 pcscd=1.8.11-3ubuntu1 libpcsclite1=1.8.11-3ubuntu1
return
}
### hold packages so they are not updated to versions that will break with GNOME
function pkghold {
echo "Marking newly installed packages from Vivid repository on hold to prevent updates"
sudo apt-mark hold gnupg2 gnupg-agent scdaemon pcscd libpcsclite1
return
}
### unhold packages incase they are previously held
function pkgunhold {
echo "Temporaily unholding packages (gnupg2, gnupg-agent, scdaemon, pcscd, libpcsclite1)"
sudo apt-mark unhold gnupg2 gnupg-agent scdaemon pcscd libpcsclite1
return
}
### Create GPG config files
function gpgconf {
echo "Creating GnuPG configuration file ~/.gnupg/gpg.conf"
# gpg.conf
cat > $gpgconf <<-EOF
default-key $keyid
no-emit-version
no-comments
keyid-format 0xlong
with-fingerprint
list-options show-uid-validity
verify-options show-uid-validity
use-agent
keyserver hkps://hkps.pool.sks-keyservers.net
keyserver-options ca-cert-file=/usr/local/etc/ssl/certs/hkps.pool.sks-keyservers.net.pem
keyserver-options no-try-dns-srv
keyserver-options no-honor-keyserver-url
keyserver-options include-revoked
personal-cipher-preferences AES256 AES192 AES CAST5
personal-digest-preferences SHA512 SHA384 SHA256 SHA224
cert-digest-algo SHA512
default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed
EOF
return
}
# gpg-agent.conf
function gpgagent {
echo "Creating ~/.gnupg/gpg-agent.conf"
cat > $gpgagent <<-EOF
enable-ssh-support
pinentry-program /usr/bin/pinentry
default-cache-ttl 60
max-cache-ttl 120
EOF
return
}
# scdaemon.conf
function scconf {
echo "Creating ~/.gnupg/scdaemon.conf and adding Yubikey IDs"
cat > $scconf <<-EOF
verbose
reader-port "Yubico Yubikey 4 OTP+U2F+CCID"
reader-port "Yubico Yubikey NEO OTP+U2F+CCID"
EOF
return
}
# scd-event
function scdevent {
echo "Creating ~/.gnupg/scd-event"
cat > $scdevent <<-EOF
#!/bin/sh
state=$8
if [ "$state" = "NOCARD" ]; then
pkill -9 scdaemon
fi
EOF
return
}
# make scd-event executable
function scexec {
echo "making scd-event executable"
chmod +x ~/.gnupg/scd-event
return
}
## create udev rules
# create 50-security-key.rules
function udev50 {
echo "Creating /etc/udev/rules.d/50-security-key.rules"
#touch /etc/udev/rules.d/50-security-key.rules
sudo sh -c 'exec cat >"$1"' sh "$udev50" <<- 'EOF'
SUBSYSTEMS=="usb", ATTRS{idVendor}=="1050", OWNER="root", GROUP="plugdev", MODE:="0660"
EOF
return
}
# create 70-u2f.rules
function udev70 {
echo "Creating /etc/udev/rules.d/70-u2f.rules"
sudo sh -c 'exec cat >"$1"' sh "$udev70" <<- 'EOF'
ACTION!="add|change", GOTO="u2f_end"
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="1050", ATTRS{idProduct}=="0113|0114|0115|0116|0120|0402|0403|0406|0407|0410", TAG+="uaccess"
LABEL="u2f_end"
EOF
return
}
# create 90-yubikey.rules
function udev90 {
echo "Creating /etc/udev/rules.d/90-yubikey.rules"
sudo sh -c 'exec cat >"$1"' sh "$udev90" <<- 'EOF'
SUBYSTEMS=="usb", ATTRS{idVendor}=="1050", ATTRS{idProduct}=="0113|0114|0115|0116|0120|0402|0403|0406|0407|0410", OWNER="root", GROUP="plugdev", MODE="0660"
EOF
return
}
### Create GNOME desktop files
# create gnome-keyring-gpg.desktop
function gnomegpg {
echo "Creating ~/.gnupg/gnome-keyring-gpg.desktop"
touch $gnomegpg
sh -c 'exec cat >"$1"' sh "$gnomegpg" <<- 'EOF'
Hidden=False
X-GNOME-Autostart-enabled=false
EOF
return
}
# create gnome-keyring-pkcs11.desktop
function gnomepk {
echo "Creating ~/.gnupg/gnome-keyring-pkcs11.desktop"
touch $gnomepk
sh -c 'exec cat >"$1"' sh "$gnomepk" <<- 'EOF'
[Desktop Entry]
Type=Application
Name=Certificate and Key Storage
Comment=GNOME Keyring: PKCS#11 Component
Exec=/usr/bin/gnome-keyring-daemon --start --components=pkcs11
OnlyShowIn=GNOME;Unity;MATE;
X-GNOME-Autostart-Phase=Initialization
X-GNOME-AutoRestart=false
X-GNOME-Autostart-Notify=true
X-GNOME-Bugzilla-Bugzilla=GNOME
X-GNOME-Bugzilla-Product=gnome-keyring
X-GNOME-Bugzilla-Component=general
X-GNOME-Bugzilla-Version=3.18.3
NoDisplay=false
X-Ubuntu-Gettext-Domain=gnome-keyring
X-GNOME-Autostart-enabled=false
EOF
return
}
# create gnome-keyring-secrets.desktop
function gnomesec {
echo "Creating ~/.gnupg/gnome-keyring-secrets.desktop"
touch $gnomesec
sh -c 'exec cat >"$1"' sh "$gnomesec" <<- 'EOF'
[Desktop Entry]
Type=Application
Name=Secret Storage Service
Comment=GNOME Keyring: Secret Service
Exec=/usr/bin/gnome-keyring-daemon --start --components=secrets
OnlyShowIn=GNOME;Unity;MATE;
X-GNOME-Autostart-Phase=Initialization
X-GNOME-AutoRestart=false
X-GNOME-Autostart-Notify=true
X-GNOME-Bugzilla-Bugzilla=GNOME
X-GNOME-Bugzilla-Product=gnome-keyring
X-GNOME-Bugzilla-Component=general
X-GNOME-Bugzilla-Version=3.18.3
NoDisplay=false
X-Ubuntu-Gettext-Domain=gnome-keyring
EOF
return
}
# create gnome-keyring-ssh.desktop
function gnomessh {
echo "Creating ~/.gnupg/gnome-keyring-ssh.desktop"
touch $gnomessh
sh -c 'exec cat >"$1"' sh "$gnomessh" <<- 'EOF'
[Desktop Entry]
Type=Application
Name=SSH Key Agent
Comment=GNOME Keyring: SSH Agent
Exec=/usr/bin/gnome-keyring-daemon --start --components=ssh
OnlyShowIn=GNOME;Unity;MATE;
X-GNOME-Autostart-Phase=Initialization
X-GNOME-AutoRestart=false
X-GNOME-Autostart-Notify=true
X-GNOME-Bugzilla-Bugzilla=GNOME
X-GNOME-Bugzilla-Product=gnome-keyring
X-GNOME-Bugzilla-Component=general
X-GNOME-Bugzilla-Version=3.18.3
X-Ubuntu-Gettext-Domain=gnome-keyring
X-GNOME-Autostart-enabled=false
EOF
return
}
# create gpg-agent.desktop
function gnomeagent {
echo "Creating ~/.gnupg/gpg-agent.desktop"
touch $gnomeagent
sh -c 'exec cat >"$1"' sh "$gnomeagent" <<- 'EOF'
[Desktop Entry]
Type=Application
Name=gpg-agent
Comment=Autostart GPG agent
Exec=/usr/bin/gpg-connect-agent /bye
Terminal=false
EOF
return
}
# added lines to .bashrc
function bashrc {
echo "Adding config lines to ~/.bashrc"
cat >> "$bashrc" <<- 'EOF'
if [ -f "${HOME}/.gpg-agent-info" ]; then
. "${HOME}/.gpg-agent-info"
export GPG_AGENT_INFO
export SSH_AUTH_SOCK
export SSH_AGENT_PID
fi
GPG_TTY=$(tty)
export GPG_TTY
EOF
return
}
# create .bash_profile
function bashpro {
echo "Creating file ~/.bash_profile"
touch $bashpro
sh -c 'exec cat >"$1"' sh "$bashpro" <<- 'EOF'
GPGKEY=$keyid
EOF
return
}
### Remove Vivid repository sources
function reporm {
echo "Removing Ubuntu Vivid repository sources"
sudo rm -Rf '$vividlist'
return
}
pkgunhold
echo "done..."
repo
echo "done..."
remove
echo "done..."
update
echo "done..."
pkginst
echo "done..."
gpgconf
echo "done..."
gpgagent
echo "done..."
scconf
echo "done..."
scdevent
echo "done..."
scexec
echo "done..."
udev50
echo "done..."
udev70
echo "done..."
udev90
echo "done..."
gnomegpg
echo "done..."
# Commented out to allow GNOME keyring to handle passwords and secrets
#gnomepk
#echo "done..."
#gnomesec
#echo "done..."
gnomessh
echo "done..."
gnomeagent
echo "done..."
bashrc
echo "done..."
bashpro
echo "done..."
reporm
echo "done..."
pkghold
echo "done..."
echo "Finished configuring configuring GNOME for GPG and SSH via Yubikey"
echo "Please go ahead not and configure your Yubikey with your GPG key"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment