This repository contains instructions to set up Fedora 41 Workstation for developing software in Go, Rust, C# (.NET Core), Java, and other languages.
See Pop!_OS Setup Guide for a version of this guide specific to Pop!_OS and Ubuntu.
Let's make sure we're on Fedora 41, which is the version of Fedora this setup guide is written for:
cat /etc/fedora-release
The terminal output should display Fedora release 41 (Forty One)
.
The first thing you should do is update Fedora:
sudo dnf upgrade
Reboot the system.
Upon logging in again, check for device firmware updates and install those updates by running the following commands:
fwupdmgr refresh --force
fwupdmgr get-updates
fwupdmgr update
Let's next install some common development tools:
sudo dnf -y install make
Install Gnome Tweaks:
sudo dnf -y install gnome-tweaks
Gnome Tweaks will let you add minimize and maximize buttons to windows, change fonts, modify font rendering behavior, and alter the appearance of the UI.
Tilix may be preferable to the default Gnome terminal:
sudo dnf install tilix
Instructions derived from https://github.com/ohmyzsh/ohmyzsh/wiki/Installing-ZSH on 2024-09-02
ZSH can be installed by running:
sudo dnf install zsh
Run zsh --version
and look for zsh 5.9 (x86_64-redhat-linux-gnu)
(or newer) to verify success
To set zsh
as the default shell, run:
chsh -s $(which zsh)
Start a new session. ZSH is now your default shell.
Oh-My-ZSH is an excellent tool for managing your ZSH configuration. Install it using the following command:
sh -c "$(wget -O- https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
An "Oh My Zsh!... is now installed!" message should appear in the terminal output.
You may be prompted to set ZSH as your default shell.
Install syntax highlighting for ZSH by running:
sudo dnf install zsh-syntax-highlighting
Now run:
echo "source /usr/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh" >> ~/.zshrc
Oh-My-ZSH is installed with several themes. Let's change the default theme to blinks
by first opening the .zshrc
file:
sudo nano ~/.zshrc
Find the line ZSH_THEME="robbyrussell"
and change it to ZSH_THEME="blinks"
and save. The new theme will be applied to new terminal windows.
Plugins add functionality to ZSH. Let's enable some pre-installed plugins for a few programming languages. First, open the .zshrc
file:
sudo nano ~/.zshrc
Find the line plugins=(git)
and change it to include your preferred plugins. An example:
plugins=(git dotnet rust golang mvn npm terraform aws gradle)
Save the file. The plugins will be applied to new terminal windows.
The instructions for installing Zed are derived from https://zed.dev/docs/linux#zed-on-linux and are current as of 2024-08-29
Zed is a highly-efficient, cross-platform code editor written in Rust.
Run the following command to install Zed:
curl https://zed.dev/install.sh | sh
To run Zed after installation, run:
zed
The instructions for installing Visual Studio Code are derived from https://code.visualstudio.com/docs/setup/linux and are current as of 2024-08-29
- Run the following commands:
sudo rpm --import https://packages.microsoft.com/keys/microsoft.asc
echo -e "[code]\nname=Visual Studio Code\nbaseurl=https://packages.microsoft.com/yumrepos/vscode\nenabled=1\ngpgcheck=1\ngpgkey=https://packages.microsoft.com/keys/microsoft.asc" | sudo tee /etc/yum.repos.d/vscode.repo > /dev/null
dnf check-update
sudo dnf install code
- Launch Visual Studio Code
- Navigate File > Preferences > Settings and then type "telemetry"
- Select "off" for the Telemetry Level
- Disable the "Dotnet Acquisition Extension: Enable Telemetry" option
- Optional: While still in Settings, change the following to "False":
- Enable Natural Language Search
- Enable Experiments
- Optional: While still in Settings, enable Editor: Format on Save. Turning this setting on is the same as running the Format Document command each time you save a file.
- Optional: While Visual Studio Code is open, select Activities, right-click the Visual Studio Code icon on the dock, and select Add to favorites.
The following VS Code extensions are handy:
- HashiCorp Terraform
- Go
- C# Dev Kit - syntax highlighting, debugging, test runner support, and intellisense for C#
- Rust-Analyzer - Rust language server
- CodeLLDB - for debugging Rust code on Ubuntu
- Extension Pack for Java - syntax highlighting, debugging, and intellisense for Java, plus unit testing support
- Spring Boot Extension Pack - specific enhancements for working with Spring Boot
- VS Live Share - allows simultaneous editing of code files by multiple authors, like Google Docs
- Docker
- Kubernetes
- JavaScript Debugger for Chrome
- Python
- ESLint
- TSLint
- Prettier
There are some excellent dark theme alternatives to the VS Code default theme:
To see which VSCode extensions are installed:
code --list-extensions
You can install VSCode extensions from the terminal, too. Run the following commands to install HashiCorp's Terraform extension, Google's Go extension, Microsoft's Docker extension, and a few others:
code --install-extension HashiCorp.terraform
code --install-extension golang.Go
code --install-extension ms-azuretools.vscode-docker
code --install-extension vscjava.vscode-java-pack
code --install-extension ms-python.python
code --install-extension ms-dotnettools.csdevkit
The instructions for installing JetBrains products are derived from https://www.jetbrains.com/help/idea/installation-guide.html#toolbox and are current as of 2024-10-08
- Visit https://www.jetbrains.com/toolbox/app/ and download the JetBrains Toolbox app.
- Run the following command, replacing the build number in the script below with the build number of the file name you downloaded:
tar -xzf jetbrains-toolbox-<build>.tar.gz && cd jetbrains-toolbox-<build> && ./jetbrains-toolbox
- Select the product that you want to install.
- Pin the Toolbox app to the Dash.
Postman is a complete toolchain for API developers.
flatpak install flathub com.getpostman.Postman
git config --global user.name "Your Name"
git config --global user.email yourname@yourdomain.com
git config --global init.defaultBranch main
See Customizing Git Configuration for more details. You can edit the global Git config file by running gedit ~/.gitconfig
in a terminal window.
Tip: Remember that you can include a longer commit message by using a second
-m
in your command. Example:git commit -m "The short message, best ~50 characters" -m "The extended description that can go on however long you want."
The instructions for generating SSH keys is derived from https://docs.github.com/en/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent. Instructions for adding an SSH key to GitHub is derived from https://docs.github.com/en/authentication/connecting-to-github-with-ssh/adding-a-new-ssh-key-to-your-github-account. Both are current as of 2024-08-29
- Run
ssh-keygen -t ed25519 -C "your_email@example.com"
- Enter a passphrase
- Run
ssh-add ~/.ssh/id_ed25519
- Run
cat ~/.ssh/id_ed25519.pub
- Copy the output from
cat
and paste it into GitLab and GitHub's SSH key sections for your profile - Run
ssh -T git@github.com
to verify the key is recognized and working with GitHub.com - Run
ssh -T git@gitlab.com
to verify the key is recognized and working with GitLab
The instructions for generating GPG keys is derived from https://docs.github.com/en/authentication/managing-commit-signature-verification/generating-a-new-gpg-key. Instructions for adding a GPG key to GitHub is derived from https://docs.github.com/en/authentication/managing-commit-signature-verification/adding-a-gpg-key-to-your-github-account. Both are current as of 2024-09-12
- Run
gpg --full-generate-key
- Choose "RSA and RSA (default)"
- Choose 4096 bits
- Choose a timeframe of your choice. It's recommended not to set an expiration.
- When providing an email, it is recommended to use your
noreply@github.com
email address. - Provide a secure passphrase.
- Run:
gpg --list-secret-keys --keyid-format=long
- From the list of GPG keys, copy the long form of the GPG key ID you'd like to use. E.g.
8FF7C99772967AA3
: - Run
gpg --armor --export 8FF7C99772967AA3
, replacing the GPG key ID with the ID produced from step 8. - Copy your GPG key, beginning with
-----BEGIN PGP PUBLIC KEY BLOCK-----
and ending with-----END PGP PUBLIC KEY BLOCK-----
. - Add the GPG key to your GitHub account.
Java is already installed by default on Fedora Workstation. To verify:
java -version
Look for an openjdk version
message to verify success.
See https://docs.fedoraproject.org/en-US/quick-docs/installing-java/ for installing different versions of Java.
sudo dnf install nodejs
To verify:
node -v
npm -v
Check for the following outputs:
v22.11.0
10.9.0
Once you've installed NodeJS using the commands from the prior section, you can install TypeScript into a specific project.
It's not recommended to install TypeScript globally, though you can via
dnf
.
# Create a new folder
mkdir typescript-test
cd typescript-test
touch app.ts
nano app.ts
Add the following to app.ts
, :
let message: string = "Hello, world!";
console.log(message);
Back in the terminal session, run:
npx tsc app.ts
node app.js
Look for Hello, world!
in the terminal output to verify success. If all of the above steps work without producing errors, then TypeScript is successfully installed at the project level in your typescript-test
folder.
When in typescript-test
, we can alternativey run:
npx tsc --init
This command creates a tsconfig.json
file with strict
mode turned on by default, which is recommended for new TypeScript projects.
Remember that tsconfig.ts
controls important behaviors of TypeScript. Some settings might be desirable for new TypeScript projects:
{
"compilerOptions": {
"noImplicitAny": true,
"strictNullChecks": true
}
}
For example, with strictNullChecks
set to true
, this code is invalid:
const x: number = null;
// invalid; can't assign null to a number type
The following code resolves the issue via the addition of | null
to the type definition:
const x: number | null = null;
// valid when strictNullChecks is true
With strictNullChecks
turned on we may need to also check for nulls explicity before using object properties, like such:
if (element) {
element.textContent = 'Hello, World!';
}
It's recommended to create new projects with
npx tsc --init
which sets thestrict
flag totrue
by default.
To debug TS in VSCode, edit your tsconfig.json
and ensure sourceMap
is set to true
:
{
"compilerOptions": {
"noImplicitAny": true,
"strictNullChecks": true,
"sourceMap": true
}
}
Run the following command in your terminal session:
npx tsc
Notice there's an app.js.map
file in addition to app.js
.
In Visual Studio Code, open the Run and Debug pane, set a breakpoint in app.ts
, and then select Run and Debug on the left side of the window. The breakpoint is hit successfully.
sudo dnf install dotnet-sdk-8.0
Run dotnet --list-sdks
and look for the following output to verify success:
8.0.110 [/usr/lib64/dotnet/sdk]
Opt out of .NET's telemetry:
- Run
nano ~/.profile
- Type
export DOTNET_CLI_TELEMETRY_OPTOUT=true
at the bottom of the file - Save and exit
- Log out and log in again
Instructions for installing Go taken from https://go.dev/doc/install on 2024-08-30
Installing Go can be done using dnf
:
sudo dnf install go
Using dnf
will likely install a slightly oudated version of Go. You can alternatively run the following commands to install an up-to-date version of Go. Be sure to replace the version number in the commands below with the version number you want to install. These are the same commands you will use to update Go to a newer version.
curl -OL https://golang.org/dl/go1.23.3.linux-amd64.tar.gz
sha256sum go1.23.3.linux-amd64.tar.gz
sudo rm -rf /usr/local/go
sudo tar -C /usr/local -xzf go1.23.3.linux-amd64.tar.gz
If you are upgrading Go using these commands, then run the following command to verify success:
go version
Look for go version go1.23.3 linux/amd64
(or newer).
If this is a first-time installation of Go, then running go version
is likely to display the following output:
bash: go: command not found...
Packages providing this file are:
'gcc-go'
'golang-bin'
You must set the following environment variables to fix the "command not found" problem after the initial Go installation. You do not need to repeat this step if you're upgrading an existing Go installation.
echo "export PATH=$PATH:$(go env GOPATH)/bin:/usr/local/go/bin" >> ~/.profile
source ~/.profile
Now run go version
and you should see the expected version number output to the terminal.
Instructions for installing Terraform taken from https://developer.hashicorp.com/terraform/cli/install/yum on 2024-09-02
sudo dnf config-manager --add-repo https://rpm.releases.hashicorp.com/fedora/hashicorp.repo
sudo dnf install terraform
Run terraform --version
to verify the installation was a success.
Instructions for installing Podman taken from https://podman.io/docs/installation on 2024-09-02
Podman is installed by default in Fedora 40 Workstation. To confirm, run:
podman run hello-world
If for some reason you don't have Podman installed you can install it using this command:
sudo dnf -y install podman
Podman Desktop is an open source graphical tool for managing containers locally, much like Docker Desktop. To install:
flatpak install flathub io.podman_desktop.PodmanDesktop
You'll be asked to go through a setup process when running Podman Desktop for the first time. Check all 3 boxes. This will install Podman Compose and kubectl
system-wide.
In Podman Desktop, find the "Kind" button on the bottom left of the window and select it. A prompt should appear asking if you want to install Kind. Select Yes. Once completed, open a terminal and run the following command to confirm:
kind get clusters
You should see this output:
enabling experimental podman provider
No kind clusters found.
Back in Podman Desktop, go to Settings > Resources and find the Kind tile. Select Create new.... Use these settings:
Name kind-cluster
Provider type: podman
HTTP port: 9090
HTTPS port: 9443
Set up ingress controller: Enabled
Node's container image: (blank)
The GUI should display "Successful operation" after a few seconds.
Navigate to the Kubernetes tab:
You should see a Kind cluster running as shown in the image above.
Confirm that your Kubernetes context is set to the local Kind cluster:
kubectl config current-context
Observe kind-kind-cluster
as the output.
If you followed along with the Podman Desktop installation instructions, you now have a Kubernetes Cluster (via Kind) and kubectl
installed. Let's now install Helm.
sudo dnf install helm
Run helm version
to verify success.
Instructions for installing Unity Hub taken from https://docs.unity3d.com/hub/manual/InstallHub.html#install-hub-linux on 2024-11-24
Run the following command to add the Unity Hub repo:
sudo sh -c 'echo -e "[unityhub]\nname=Unity Hub\nbaseurl=https://hub.unity3d.com/linux/repos/rpm/stable\nenabled=1\ngpgcheck=1\ngpgkey=https://hub.unity3d.com/linux/repos/rpm/stable/repodata/repomd.xml.key\nrepo_gpgcheck=1" > /etc/yum.repos.d/unityhub.repo'
Update the package cache and install:
sudo yum check-update
sudo yum install unityhub
You can now run the Unity Hub app. Once logged in, select Install Unity Editor.
In the Unity Hub, be sure to navigate to Preferences > Privacy and opt out of "Analytics". It is opt-in by default.
Removing Unity Hub can be done by running
$ sudo yum remove unityhub
Instructions taken from https://discussions.unity.com/t/can-not-activate-license-in-unity-hub-on-fedora-41-rhel9-until-trust-sha-1/1520652/17 on 2024-12-01
Fedora 41 no longer allows SHA-1. This means SHA-1-based Unity licenses cannot be activated. Rather than displaying an error, however, the license process in Unity Hub fails without any messages as to why. This can lead users down a long road of troubleshooting things and ultimately wastes time.
Fixing this involves updating Fedora's crypto policies to allow SHA-1, which unfortunately, can be a degradation of system security. Thankfully we can isolate the allowed use of SHA-1 to just Unity Hub:
sudo update-crypto-policies --set DEFAULT:SHA1
cp /etc/crypto-policies/back-ends/opensslcnf.config ~/my-insecure-unity-opensslcnf.config
sudo update-crypto-policies --set DEFAULT
The above commands create a crypto policy config file that allows SHA-1. The default system-wide crypto policy is not permanently altered. You can run Unity with this new policy applied by running:
OPENSSL_CONF=~/my-insecure-unity-opensslcnf.config unityhub
You can run
sudo update-crypto-policies --set DEFAULT:SHA1
and not deal with the configuration file if you don't mind the security implications.
This section will be updated if and when Unity adopts an algorithm that no longer runs afoul of Fedora's default crypto policies.
Fedora has a package for AWS CLI tooling:
sudo dnf install awscli
Run aws --version
to verify success.
The simplest way to install the Azure CLI tools:
sudo dnf install azure-cli
Verify success by running az --version
. Note that installing via dnf
will install an older version of the Azure CLI tools.
You cannot run az upgrade
to upgrade the Azure CLI tools when they were installed using dnf
.
See Install Azure CLI on Linux for alternative installation methods that will ensure newer versions are installed.
One can run PostgreSQL in a container rather than installing locally. We can also start a second PostgreSQL container to connect to the first container and run commands.
The advantage to using a second PostgreSQL container to run SQL commands is that we don't need to install PostgreSQL tools locally.
While Podman and Docker are similar, the rootless nature of Podman containers means the required commands to make container-to-container networking function correctly differ between the two tools. This guide is specific to Podman. Making a similar connection using Docker would require creating a new network in
bridge
mode and setting both containers to use that network, which is not possible in Podman without using rootful containers.
Let's get started.
- First create a pod:
podman pod create --name test-pod1 --share net -p 5432:5432
- Next, create and run the main PostgreSQL container that you want to use as the database server:
podman run --pod test-pod1 --detach --rm --name test-container1 --env POSTGRES_PASSWORD=my-secret-pw postgres:latest
- Finally, create the second PostgreSQL container that you want to use for issuing commands to the first container:
podman run --pod test-pod1 -it --rm --name test-container2 postgres psql -U postgres -h localhost -p 5432 -d postgres
After step 3, you should see a postgres=#
prompt. Type SELECT table_name FROM information_schema.tables;
and press Enter to verify success. Type q
to exit the table list view.
You can always open Podman Desktop to easily delete pods and containers if you mess things up.
Go PostgreSQL example code is a runnable Go program that should "just work" if you followed the steps above.
package main
import (
"database/sql"
"fmt"
_ "github.com/lib/pq"
)
const (
host = "localhost"
port = 5432
user = "postgres"
password = "my-secret-pw"
dbname = "postgres"
)
func main() {
// connection string
psqlconn := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=disable", host, port, user, password, dbname)
// open database
db, err := sql.Open("postgres", psqlconn)
CheckError(err)
sql := `SELECT datname FROM pg_database`
rows, err := db.Query(sql)
CheckError(err)
defer rows.Close()
for rows.Next() {
var datname string
err = rows.Scan(&datname)
CheckError(err)
fmt.Println(datname)
}
// close database
defer db.Close()
// check db
err = db.Ping()
CheckError(err)
fmt.Println("Connected!")
}
func CheckError(err error) {
if err != nil {
panic(err)
}
}
Let's run the Go code example from the app-examples
folder in this repository:
cd ./app-examples/golang-postgres
go get github.com/lib/pq
go run .
You should see the following output:
postgres
template1
template0
Connected!
Dev Containers are a way to containerize your development environment. They make your development setup portable and consistent.
However, one thing we must do is configure the Dev Containers VSCode extension to use Podman instead of Docker. This is because the Dev Containers extension assumes you have Docker, but the Fedora Setup guide is using Podman instead. If you've followed along with this guide, how would you go about configuring this?
-
First, get the Dev Containers extension for Visual Studio Code.
-
Open File > Preferences > Settings in Visual Studio Code.
-
Type "Dev Containers" into the Settings search box.
-
Change Dev > Containers: Docker Compose Path to
podman compose
-
Change Dev > Containers: Docker Path to
podman
-
Change Dev > Containers: Docker Socket Path to
unix:///run/user/1000/podman/podman.sock
.
This is also a good time to update your Docker VSCode extension settings to work with Podman:
-
Type "Docker" into the Settings search box.
-
Change Docker: Docker Path to
podman
. -
Change Docker: Docker Compose Path to
podman compose
. -
Add a new environment variable to Docker: Environment with item =
DOCKER_HOST
and value =unix:///run/user/1000/podman/podman.sock
.
Now let's look at an example devcontainer.json
file that might appear in a repository:
{
"name": "name here",
"image": "path-to-image-here",
"containerUser": "vscode",
"updateRemoteUserUID": true,
"containerEnv": {
"HOME": "/home/vscode"
},
"runArgs": [
"--userns=keep-id:uid=1000,gid=1000"
]
}
Setting containerUser
to "vscode" ensures that the container uses the vscode
user to create workspaces. Otherwise, the container might try to create workspaces under /root
, which will fail in Podman.
This ensures that the vscode
user is really mapped inside of the container, and it also ensures that vscode
's HOME is set explicitly.
You may still run into trouble with DevContainers using these steps above. Most DevContainer examples assume you're running rootful containers under Docker and not rootless containers in Podman.
Instructions derived from https://docs.fedoraproject.org/en-US/quick-docs/virtualization-getting-started/ and https://fedoramagazine.org/full-virtualization-system-on-fedora-workstation-30/
We can use Linux's built-in Kernel Virtual Machine (KVM) plus QEMU and VirtManager to build, run, and manage VMs.
sudo dnf install @virtualization
Now start the service:
sudo systemctl start libvirtd
Start the service on boot by running:
sudo systemctl enable libvirtd
Verify success by looking for kvm_intel
or kvm_amd
in the following:
lsmod | grep kvm
You'll want to administer libvirt
with the regular user. Otherwise, every time you start virt-manager
you will need to do so with sudo
and enter your password.
sudo usermod -a -G libvirt $(whoami)
Now log out and log in again.
- Download the Fedora Silverblue ISO or the ISO of your choice
- Place the
.iso
file into the/var/lib/libvirt/images
folder:
cd ~/Downloads
sudo mv Fedora-Silverblue-ostree-x86_64-41-1.4.iso /var/lib/libvirt/images
- Open the Virtual Machine Manager (aka
virt-manager
) - Add a new virtual machine. Note that if you get a connection error, you should reboot your machine.
- Select Local install media and then Forward. Step 2 of 5 appears.
- Select Browse. The ISO you copied into the
/var/lib/libvirt/images
folder should appear. - Select the ISO and choose Choose Volume
- You may need to select an operating system. if Virtual Machine Manager couldn't auto-detect one based on the ISO. In our case, using Fedora Silverblue, "Fedora Silverblue 40" is auto-detected and we can skip manual OS selection.
- Select Forward
- Choose at least "8192" for memory and 2 CPUs and then select Forward
- Choose at least 25 GB of disk storage and select Forward
- Use a distinctive name for the VM and select Finish
- The VM should start automatically. Go through the VM setup process.
On 4K monitors the VM image may be tiny. You can use a virt-manager
setting to try and adjust this:
- Select View
- Select Scale Display
- Check the box titled Auto resize VM with window.
Snapshots can be taken in virt-manager
just like in Virtual Box. You must navigate into the VM window (not the Virtual Machine Manager window) and select the Manage VM Snapshots icon at the far right of the toolbar.
The button to create a snapshot is the + (plus) symbol on the bottom left of the window.
See https://wiki.mozilla.org/Privacy/Privacy_Task_Force/firefox_about_config_privacy_tweeks for advanced privacy-related Firefox configuration options.
This Fedora 40 Setup Guide does not list all the options on the site above. It's recommended you visit that site and decide on each option for yourself. However, a few privacy tweaks are important enough that they are worth mentioning here.
Open about:config
in your Firefox URL bar and accept the warning to proceed with making these privacy tweaks.
dom.private-attribution.submission.enabled = false
Attribution is a way to track whether ads served to you were effective in getting you to buy something. More information is available at https://github.com/mozilla/explainers/tree/main/ppa-experiment. The above command disables this feature.
privacy.resistFingerprinting = true
This setting improves your defenses against browser fingerprinting.
dom.event.clipboardevents.enabled = false
This setting prevents websites from knowing if you used copy or paste commands and what part of the page you had selected when you used those commands.
webgl.disabled = true
This command disables WebGL. If you never visit sites with WebGL content then it can be safely disabled.
Enabling USBGuard in Fedora 41 may cause the OS to hard-lock on reboot or power off and prevent virtual machines from starting. This section will be updated with more details as they become available.
USBGuard enables you to block USB device access. This is useful for protecting against rogue USB devices (think "BadUSB") by implementing a USB blocklist and USB device policy.
Warning: Installing USBGuard using the steps below will create a policy that allows only currently-connected USB devices to be usable on the next boot. You can and should review this policy right after installation to ensure you can continue to use your PC. For instance, if you use hardware security keys to login, and they were not inserted at the time of USBGuard's installation, you could be locked out of your system permanently. Be cautious.
Let's install USB Guard:
sudo dnf install usbguard
You should also consider installing the USB viewer app, though this is optional:
sudo dnf install usbview
You can then graphically view USB devices by running:
usbview
Or through either of these terminal commands:
lsusb
usb-devices | less
We now need to start and then stop the USB Guard service to populate the rules.conf
file:
sudo systemctl enable usbguard.service --now
sudo systemctl start usbguard.service
sudo systemctl stop usbguard.service
Let's now set an initial policy:
usbguard generate-policy -X -t reject > /etc/usbguard/rules.conf
Now let's modify these configuration files. Open a root terminal and navigate to the usbguard
directory:
sudo -i
cd /etc/usbguard
ls -laF
Look for rules.conf
and usbguard-daemon.conf
.
Let's look at the USBGuard policy:
sudo grep -vE '^#|^$' /etc/usbguard/usbguard-daemon.conf
RuleFile=/etc/usbguard/rules.conf
RuleFolder=/etc/usbguard/rules.d/
ImplicitPolicyTarget=block
PresentDevicePolicy=apply-policy
PresentControllerPolicy=keep
InsertedDevicePolicy=apply-policy
RestoreControllerDeviceState=false
DeviceManagerBackend=uevent
IPCAllowedUsers=root
IPCAllowedGroups=wheel
IPCAccessControlFiles=/etc/usbguard/IPCAccessControl.d/
DeviceRulesWithPort=false
AuditBackend=FileAudit
AuditFilePath=/var/log/usbguard/usbguard-audit.log
HidePII=false
See ImplicitPolicyTarget=block
on line 3. This line tells the daemon how to treat USB devices that fail to match a rule in the policy. Allowed values are allow
, block
or reject
. A policy of reject
logically removes the device node from the system.
See PresentDevicePolicy
on line 4. This line tells the daemon how to treat USB devices that are already connected when the daemon starts. Allowed values are allow
, block
, reject
, keep
(this maintains the state the device is in) or apply-policy
. The apply-policy
default simply means to apply the rules to each USB device.
You can find further documentation at https://usbguard.github.io/documentation/configuration.
Let's look at the default ruleset that was created when we started and then stopped the daemon:
sudo nano /etc/usbguard/rules.conf
You should see that all currently connected devices are listed with allow
as the permission. If you're on a laptop with no devices connected then the file is likely to be empty.
Let's start the daemon and check to see if it's working:
sudo systemctl restart usbguard.service
sudo systemctl status usbguard.service
sudo usbguard list-rules
You can list all USB devices recognized by the daemon:
sudo usbguard list-devices
You can verify it's working by plugging in a USB device and running:
lsusb
Look for the USB device in the list. It should appear, but it shouldn't work - that is, if you plugged in a USB thumb drive, it shouldn't appear as new storage. Let's confirm by running this command:
sudo dmesg | grep -i 'authorized'
If you see the following message or type of message then USBGuard successfully blocked the device:
[xxxxx.xxxxxx] usb x-x.x: Device is not authorized for usage
Let's authorize the device. We first need to find the device id and serial number. Run this command to list all the blocked devices:
sudo usbguard list-devices -b
Note the device ID and serial number. You will need these values. Then run the command below. Before doing so, replace the 1234:5678
and ABCDEF
with the values outputted from the sudo usbguard list-devices -b
command. Executing this command permanently updates the rules.conf
with an allow
rule for that device.
The
-p
flag is for permanent; leaving it off the command would make this a temporary rule that would not persist across a reboot.
If your device has no serial number, just leave the serial number empty. Example:
""
sudo usbguard allow-device '1234:5678 serial "ABCDEF"' -p
Restart the USBGuard service:
sudo systemctl restart usbguard.service
With your device still plugged in, run:
sudo usbguard list-devices -b
If your device does not appear in the list of blocked devices then you've successfully whitelisted it.
Lastly, let's cover some useful keyboard shortcuts for Gnome. You can find a full list at https://help.gnome.org/users/gnome-help/stable/shell-keyboard-shortcuts.html.en, but a subset are called out here, especially for those switching from other distros or from Windows.
Key Combo | Action |
---|---|
Super + TAB |
Switches between windows, much like ALT + TAB in Windows. Caveat: If you have multiple windows of the same app (e.g. two Firefox windows), this key combo won't switch between them. You'll need to use the down arrow key to expand the 'Firefox' selection into its list of windows, then use the left/right arrow keys to select the window you want. |
ALT + ESC |
Switches between windows in the current workspace. Unlike Super + TAB , this does switch between different windows for the same app. |
Super + A |
Shows the list of applications. |
Super + L |
Locks the screen. Same behavior as Windows. |
Super + V |
Shows the notification screen, including the calendar. Press again to make it disappear. |
ALT + F2 |
Run a command. |
ALT + Prnt Scrn |
Take a screenshot of the active window. |
Shift + Prnt Scrn |
Take a screenshot of a screen area. |
The easiest way to install a font is to download it, extract the contents, and then double-click on the .ttf
file. This opens Gnome Font Viewer. In the Gnome Font Viewer window, select the blue Install button to install the font.
Alternatively, fonts can be installed by downloading a font and placing it into a ffont family older inside of /.local/share/fonts
.
Let's walk through what this would look like. First, download the Inter font from Google Fonts to your /Downloads
folder.
mkdir -p ~/.local/share/fonts/Inter
cd ~/Downloads
unzip Inter.zip -d Inter/
cp ~/Downloads/Inter-VariableFont_opsz,wght.ttf ~/.local/share/fonts/Inter