The Domain Name System (DNS) that modern computers use to find resources on the internet was designed 35 years ago without consideration for user privacy. It is exposed to security risks and attacks like DNS Hijacking. It also allows ISPs to intercept the queries.
Luckily, DNS over TLS and DNSSEC are available. DNS over TLS and DNSSEC allow safe and encrypted end-to-end tunnels to be created from a computer to its configured DNS servers. On Fedora, the steps to implement these technologies are easy and all the necessary tools are readily available.
This guide will demonstrate how to configure DNS over TLS on Fedora using systemd-resolved. Refer to the documentation for further information about the systemd-resolved service.
Step 1 : Set-up systemd-resolved
Modify /etc/systemd/resolved.conf so that it is similar to what is shown below. Be sure to enable DNS over TLS and to configure the IP addresses of the DNS servers you want to use.
DNS: A space-separated list of IPv4 and IPv6 addresses to use as system DNS servers
FallbackDNS: A space-separated list of IPv4 and IPv6 addresses to use as the fallback DNS servers.
Domains: These domains are used as search suffixes when resolving single-label host names, ~. stand for use the system DNS server defined with DNS= preferably for all domains.
DNSOverTLS: If true all connections to the server will be encrypted. Note that this mode requires a DNS server that supports DNS-over-TLS and has a valid certificate for it’s IP.
NOTE: The DNS servers listed in the above example are my personal choices. You should decide which DNS servers you want to use; being mindful of whom you are asking IPs for internet navigation.
Step 2 : Tell NetworkManager to push info to systemd-resolved
Create a file in /etc/NetworkManager/conf.d named 10-dns-systemd-resolved.conf.
The setting shown above (dns=systemd-resolved) will cause NetworkManager to push DNS information acquired from DHCP to the systemd-resolved service. This will override the DNS settings configured in Step 1. This is fine on a trusted network, but feel free to set dns=none instead to use the DNS servers configured in /etc/systemd/resolved.conf.
Step 3 : start & restart services
To make the settings configured in the previous steps take effect, start and enable systemd-resolved. Then restart NetworkManager.
CAUTION: This will lead to a loss of connection for a few seconds while NetworkManager is restarting.
NOTE: Currently, the systemd-resolved service is disabled by default and its use is opt-in. There are plans to enable systemd-resolved by default in Fedora 33.
Step 4 : Check if everything is fine
Now you should be using DNS over TLS. Confirm this by checking DNS resolution status with:
$ resolvectl status
MulticastDNS setting: yes DNSOverTLS setting: yes DNSSEC setting: yes DNSSEC supported: yes Current DNS Server: 1.1.1.1 DNS Servers: 1.1.1.1 9.9.9.9 Fallback DNS Servers: 8.8.8.8 1.0.0.1 8.8.4.4
/etc/resolv.conf should point to 127.0.0.53
$ cat /etc/resolv.conf
# Generated by NetworkManager
search lan
nameserver 127.0.0.53
To see the address and port that systemd-resolved is sending and receiving secure queries on, run:
$ sudo ss -lntp | grep '\(State\|:53 \)'
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:* users:(("systemd-resolve",pid=10410,fd=18))
To make a secure query, run:
$ resolvectl query fedoraproject.org
fedoraproject.org: 8.43.85.67 -- link: wlp58s0 8.43.85.73 -- link: wlp58s0 [..] -- Information acquired via protocol DNS in 36.3ms.
-- Data is authenticated: yes
BONUS Step 5 : Use Wireshark to verify the configuration
It will ask you which link device it have to begin capturing packets on. In my case, because I use a wireless interface, I will go ahead with wlp58s0. Set up a filter in Wireshark like tcp.port == 853 (853 is the DNS over TLS protocol port). You need to flush the local DNS caches before you can capture a DNS query:
$ sudo resolvectl flush-caches
Now run:
$ nslookup fedoramagazine.org
You should see a TLS-encryped exchange between your computer and your configured DNS server:
— Poster in Cover Image Approved for Release by NSA on 04-17-2018, FOIA Case # 83661 —
The Rosetta@home project is a not-for-profit distributed computing project created by the Baker laboratory at the University of Washington. The project uses idle compute capacity from volunteer computers to study protein structure, which is used in research into diseases such as HIV, Malaria, Cancer, and Alzheimer’s.
In common with many other scientific organizations, Rosetta@home is currently expending significant resources on the search for vaccines and treatments for COVID-19.
Rosetta@home uses the open source BOINC platform to manage donated compute resources. BOINC was originally developed to support the SETI@home project searching for Extraterrestrial Intelligence. These days, it is used by a number of projects in many different scientific fields. A single BOINC client can contribute compute resources to many such projects, though not all projects support all architectures.
For the example shown in this article a Raspberry Pi 3 Model B was used, which is one of the tested reference devices for Fedora IoT. This device, with only 1GB of RAM, is only just powerful enough to be able to make a meaningful contribution to Rosetta@home, and there’s certainly no way the Raspberry Pi can be used for anything else – such as running a desktop environment – at the same time.
It’s also worth mentioning at this point that the first rule of Raspberry Pi computing is to get the recommended power supply. It is important to get as close to the specified 2.5A as you can, and use a good quality micro-usb cable.
Then use the arm-image-installer utility (sudo dnf install fedora-arm-installer) to write the image to the SD card. As always, be very sure which device name corresponds to your SD Card before continuing. Check the device with the lsblk command like this:
$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sdb 8:16 1 59.5G 0 disk
└─sdb1 8:17 1 59.5G 0 part /run/media/gavin/154F-1CEC
nvme0n1 259:0 0 477G 0 disk
├─nvme0n1p1 259:1 0 600M 0 part
...
If you’re still not sure, try running lsblk with the SD card removed, then again with the SD card inserted and comparing the outputs. In this case it lists the SD card as /dev/sdb. If you’re really unsure, there are some more tips described in the Getting Started guide.
We need to tell arm-image-installer which image file to use, what type of device we’re going to be using, and the device name – determined above – to use for writing the image. The arm-image-installer utility is also able to expand the filesystem to use the entire SD card at the point of writing the image.
Since we’re not going to use the zezere provisioning server to deploy SSH keys to the Raspberry Pi, we need to specify the option to remove the root password so that we can log in and set it at first boot.
= Selected Image: = /var/home/gavin/Downloads/Fedora-IoT-32-20200603.0.aarc...
= Selected Media : /dev/sdb
= U-Boot Target : rpi3
= Root Password will be removed.
= Root partition will be resized
===================================================== *****************************************************
*****************************************************
******** WARNING! ALL DATA WILL BE DESTROYED ********
*****************************************************
***************************************************** Type 'YES' to proceed, anything else to exit now
the image is written to the SD Card.
...
= Installation Complete! Insert into the rpi3 and boot.
Booting the Raspberry Pi
For the initial setup, you’ll need to attach a keyboard and mouse to the Raspberry Pi. Alternatively, you can follow the instructions for connecting with a USB-to-Serial cable.
When the Raspberry Pi boots up, just type root at the login prompt and press enter.
localhost login: root
[root@localhost~]#
The first task is to set a password for the root user.
[root@localhost~]# passwd
Changing password for user root.
New password: Retype new password:
passwd: all authentication tokens updated successfully
[root@localhost~]#
Verifying Network Connectivity
To verify the network connectivity, the checklist in the Fedora IoT Getting Started guide was followed. This system is using a wired ethernet connection, which shows as eth0. If you need to set up a wireless connection this can be done with nmcli.
ip addr will allow you to check that you have a valid IP address.
[root@localhost ~]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether b8:27:eb:9d:6e:13 brd ff:ff:ff:ff:ff:ff
inet 192.168.178.60/24 brd 192.168.178.255 scope global dynamic noprefixroute eth0
valid_lft 863928sec preferred_lft 863928sec
inet6 fe80::ba27:ebff:fe9d:6e13/64 scope link
valid_lft forever preferred_lft forever
3: wlan0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc fq_codel state DOWN group default qlen 1000
link/ether fe:d3:c9:dc:54:25 brd ff:ff:ff:ff:ff:ff
ip route will check that the network has a default gateway configured.
[root@localhost ~]# ip route
default via 192.168.178.1 dev eth0 proto dhcp metric 100 192.168.178.0/24 dev eth0 proto kernel scope link src 192.168.178.60 metric 100
To verify internet access and name resolution, use ping
[root@localhost ~]# ping -c3 iot.fedoraproject.org
PING wildcard.fedoraproject.org (8.43.85.67) 56(84) bytes of data.
64 bytes from proxy14.fedoraproject.org (8.43.85.67): icmp_seq=1 ttl=46 time=93.4 ms
64 bytes from proxy14.fedoraproject.org (8.43.85.67): icmp_seq=2 ttl=46 time=90.0 ms
64 bytes from proxy14.fedoraproject.org (8.43.85.67): icmp_seq=3 ttl=46 time=91.3 ms --- wildcard.fedoraproject.org ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 90.043/91.573/93.377/1.374 ms
Optional: Configuring sshd so we can disconnect the keyboard and monitor
Before disconnecting the keyboard and monitor, we need to ensure that we can connect to the Raspberry Pi over the network.
First we verify that sshd is running
[root@localhost~]# systemctl is-active sshd
active
and that there is a firewall rule present to allow ssh.
[root@localhost ~]# firewall-cmd --list-all
public (active) target: default icmp-block-inversion: no interfaces: eth0 sources: services: dhcpv6-client mdns ssh ports: protocols: masquerade: no forward-ports: source-ports: icmp-blocks: rich rules:
In the file /etc/ssh/sshd_config, find the section named
# Authentication
and add the line
PermitRootLogin yes
There will already be a line
#PermitRootLogin prohibit-password
which you can edit by removing the # comment character and changing the value to yes.
Restart the sshd service to pick up the change
[root@localhost ~]# systemctl restart sshd
If all this is in place, we should be able to ssh to the Raspberry Pi.
[gavin@desktop ~]$ ssh root@192.168.178.60
The authenticity of host '192.168.178.60 (192.168.178.60)' can't be established.
ECDSA key fingerprint is SHA256:DLdFaYbvKhB6DG2lKmJxqY2mbrbX5HDRptzWMiAUgBM.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '192.168.178.60' (ECDSA) to the list of known hosts.
root@192.168.178.60's password: Boot Status is GREEN - Health Check SUCCESS
Last login: Wed Apr 1 17:24:50 2020
[root@localhost ~]#
It’s now safe to log out from the console (exit) and disconnect the keyboard and monitor.
Disabling unneeded services
Since we’re right on the lower limit of viable hardware for Rosetta@home, it’s worth disabling any unneeded services. Fedora IoT is much more lightweight than desktop distributions, but there are still a few optimizations we can do.
Like disabling bluetooth, Modem Manager (used for cellular data connections), WPA supplicant (used for Wi-Fi) and the zezere services, which are used to centrally manage a fleet of Fedora IoT devices.
[root@localhost /]# for serviceName in bluetooth ModemManager wpa_supplicant zezere_ignition zezere_ignition.timer zezere_ignition_banner; do sudo systemctl stop $serviceName; sudo systemctl disable $serviceName; sudo systemctl mask $serviceName; done
Getting the BOINC client
Instead of installing the BOINC client directly onto the operating system with rpm-ostree, we’re going to use podman to run the containerized version of the client.
This image uses a volume mount to store its data, so we create the directories it needs in advance.
We can inspect the container logs to make sure everything is working as expected:
[root@localhost ~]# podman logs boinc
20-Jun-2020 09:02:44 [---] cc_config.xml not found - using defaults
20-Jun-2020 09:02:44 [---] Starting BOINC client version 7.14.12 for aarch64-unknown-linux-gnu
...
...
...
20-Jun-2020 09:02:44 [---] Checking presence of 0 project files
20-Jun-2020 09:02:44 [---] This computer is not attached to any projects
20-Jun-2020 09:02:44 Initialization completed
Configuring the BOINC container to run at startup
We can automatically generate a systemd unit file for the container with podman generate systemd.
You need to create an account at the Rosetta@home signup page, and retrieve your account key from your account home page. The key to copy is the “Weak Account Key”.
Finally, we execute the boinccmd configuration utility inside the container using podman exec, passing the Rosetta@home url and our account key.
Running podman logs –follow boinc will allow us to see the container connecting to the project. You will probably see errors of the form
20-Jun-2020 10:18:40 [Rosetta@home] Rosetta needs 1716.61 MB RAM but only 845.11 MB is available for use.
This is because most, but not all, of the work units in Rosetta@Home require more memory than we have to offer. However, if you leave the device running for a while, it should eventually get some jobs to process. The polling interval seems to be approximately 10 minutes. We can also tweak the memory settings using BOINC manager to allow BOINC to use slightly more memory. This will increase the probability that Rosetta@home will be able to find tasks for us.
Installing BOINC Manager for remote access
You can use dnf to install the BOINC manager component to remotely manage the BOINC client on the Raspberry Pi.
[gavin@desktop ~]$ sudo dnf install boinc-manager
If you switch to “Advanced View” , you will be able to select “File -> Select Computer” and connect to your Raspberry Pi, using the IP address of the Pi and the value supplied for BOINC_GUI_RPC_PASSWORD in the podman run command, in my case “blah“.
Press Shift+Ctrl+I to connect BOINC manager to a remote computer
Under “Options -> Computing Preferences”, increase the value for “When Computer is not in use, use at most _ %”. I’ve been using 93%; this seems to allow Rosetta@home to schedule work on the pi, whilst still leaving it just about usable. It is possible that further fine tuning of the operating system might allow this percentage to be increased.
Using the Computing Preferences Dialog to set the memory threshhold
These settings can also be changed through the Rosetta@home website settings page, but bear in mind that changes made through the BOINC Manager client override preferences set in the web interface.
Wait
It may take a while, possibly several hours, for Rosetta@home to send work to our newly installed client, particularly as most work units are too big to run on a Raspberry Pi. COVID-19 has resulted in a large number of new computers being joined to the Rosetta@home project, which means that there are times when there isn’t enough work to do.
When we are assigned some work units, BOINC will download several hundred megabytes of data. This will be stored on the SD Card and can be viewed using BOINC manager.
We can also see the tasks running in the Tasks pane:
The client has downloaded four tasks, but only one of them is currently running due to memory constraints. At times, two tasks can run simultaneously, but I haven’t seen more than that. This is OK as long as the tasks are completed by the deadline shown on the right. I’m fairly confident these will be completed as long as the Raspberry Pi is left running. I have found that the additional memory overhead created by the BOINC Manager connection and sshd services can reduce parallelism, so I try to disconnect these when I’m not using them.
Conclusion
Rosetta@home, in common with many other distributed computing projects, is currently experiencing a large spike in participation due to COVID-19. That aside, the project has been doing valuable work for many years to combat a number of other diseases.
Whilst a Raspberry Pi is never going to appear at the top of the contribution chart, I think this is a worthwhile project to undertake with a spare Raspberry Pi. The existence of work units aimed at low-spec ARM devices indicates that the project organizers agree with this sentiment. I’ll certainly be leaving mine running for the foreseeable future.
The outermost layer of your operating system – the part you interact with – is called the shell. Fedora comes with several preinstalled shells. Shells can be either graphical or text-based. In documentation, you will often see the acronyms GUI (Graphical User Interface) and CLI (Command-Line Interface) used to distinguish between graphical and text-based shells/interfaces. Other GUI and CLI shells can be used, but GNOME is Fedora’s default GUI and Bash is its default CLI.
The remainder of this article will cover recommended dotfile practices for the Bash CLI.
Bash overview
From the Bash reference manual:
At its base, a shell is simply a macro processor that executes commands. The term macro processor means functionality where text and symbols are expanded to create larger expressions.
Reference Documentation for Bash Edition 5.0, for Bash Version 5.0. May 2019
In addition to helping the user start and interact with other programs, the Bash shell also includes several built-in commands and keywords. Bash’s built-in functionality is extensive enough that it is considered a high-level programming language in its own right. Several of Bash’s keywords and operators resemble those of the C programming language.
Bash can be invoked in either interactive or non-interactive mode. Bash’s interactive mode is the typical terminal/command-line interface that most people are familiar with. GNOME Terminal, by default, launches Bash in interactive mode. An example of when Bash runs in non-interactive mode is when commands and data are piped to it from a file or shell script. Other modes of operation that Bash can operate in include: login, non-login, remote, POSIX, unix sh, restricted, and with a different UID/GID than the user. Various combinations of these modes are possible. For example interactive+restricted+POSIX or non-interactive+non-login+remote. Which startup files Bash will process depends on the combination of modes that are requested when it is invoked. Understanding these modes of operation is necessary when modifying the startup files.
According to the Bash reference manual, Bash …
1. Reads its input from a file …, from a string supplied as an argument to the -c invocation option …, or from the user’s terminal.
2. Breaks the input into words and operators, obeying [its] quoting rules. … These tokens are separated by metacharacters. Alias expansion is performed by this step.
3. Parses the tokens into simple and compound commands.
4. Performs the various shell expansions …, breaking the expanded tokens into lists of filenames … and commands and arguments.
5. Performs any necessary redirections … and removes the redirection operators and their operands from the argument list.
6. Executes the command.
7. Optionally waits for the command to complete and collects its exit status.
Reference Documentation for Bash Edition 5.0, for Bash Version 5.0. May 2019
When a user starts a terminal emulator to access the command line, an interactive shell session is started. GNOME Terminal, by default, launches the user’s shell in non-login mode. Whether GNOME Terminal launches the shell in login or non-login mode can be configured under Edit → Preferences → Profiles → Command. Login mode can also be requested by passing the –login flag to Bash on startup. Also note that Bash’s login and non-interactive modes are not exclusive. It is possible to run Bash in both login and non-interactive mode at the same time.
Invoking Bash
Unless it is passed the —noprofile flag, a Bash login shell will read and execute the commands found in certain initialization files. The first of those files is /etc/profile if it exists, followed by one of ~/.bash_profile, ~/.bash_login, or ~/.profile; searched in that order. When the user exits the login shell, or if the script calls the exit built-in in the case of a non-interactive login shell, Bash will read and execute the commands found in ~/.bash_logout followed by /etc/bash_logout if it exists. The file /etc/profile will normally source /etc/bashrc, reading and executing commands found there, then search through /etc/profile.d for any files with an sh extension to read and execute. As well, the file ~/.bash_profile will normally source the file ~/.bashrc. Both /etc/bashrc and ~/.bashrc have checks to prevent double sourcing.
An interactive shell that is not a login shell, will source the ~/.bashrc file when it is first invoked. This is the usual type of shell a user will enter when opening a terminal on Fedora. When Bash is started in non-interactive mode – as it is when running a shell script – it will look for the BASH_ENV variable in the environment. If it is found, will expand the value, and use the expanded value as the name of a file to read and execute. Bash behaves just as if the following command were executed:
if [ -n "$BASH_ENV" ]; then . "$BASH_ENV"; fi
It is important to note that the value of the PATH variable is not used to search for the filename.
Important user-specific dotfiles
Bash’s best-known user dotfile is ~/.bashrc. Most user customization is done by editing this file. Most user customization, may be a stretch since there are reasons to modify all of the mentioned files; as well as other files that have not been mentioned. Bash’s environment is designed to be highly customizable in order to suit the needs of many different users with many different tastes.
When a Bash login shell exits cleanly, ~/.bash_logout and then /etc/bash_logout will be called if they exist. The next diagram is a sequence diagram showing the process Bash follows when being invoked as an interactive shell. The below sequence is followed, for example, when the user opens a terminal emulator from their desktop environment.
Armed with the knowledge of how Bash behaves under different invocation methods, it becomes apparent that there are only a few typical invocation methods to be most concerned with. These are the non-interactive and interactive login shell, and the non-interactive and interactive non-login shell. If global environment customizations are needed, then the desired settings should be placed in a uniquely-named file with a .sh extension (custom.sh, for example) and that file should be placed in the /etc/profile.d directory.
The non-interactive, non-login invocation method needs special attention. This invocation method causes Bash to check the BASH_ENV variable. If this variable is defined, the file it references will be sourced. Note that the values stored in the PATH environment variable are not utilized when processing BASH_ENV. So it must contain the full path to the file to be sourced. For example, if someone wanted the settings from their ~/.bashrc file to be available to shell scripts they run non-interactively, they could place something like the following in a file named /etc/profile.d/custom.sh …
The above profile drop-in script will cause the user’s ~/.bashrc file to be sourced just before every shell script is executed.
Users typically customizie their system environment so that it will better fit their work habits and preferences. An example of the sort of customization that a user can make is an alias. Commands frequently run with the same set of starting parameters are good candidates for aliases. Some example aliases are provided in the ~/.bashrc file shown below.
# .bashrc
# Source global definitions
if [ -f /etc/bashrc ]; then . /etc/bashrc
fi
.
.
.
# User specific aliases and functions
alias ls='ls -hF --color=auto'
alias la='ls -ahF --color=auto'
# make the dir command work kinda like in windows (long format)
alias dir='ls --color=auto --format=long'
# make grep highlight results using color
alias grep='grep --color=auto'
Aliases are a way to customize various commands on your system. They can make commands more convenient to use and reduce your keystrokes. Per-user aliases are often configured in the user’s ~/.bashrc file.
If you find you are looking back through your command line history a lot, you may want to configure your history settings. Per-user history options can also be configured in ~/.bashrc. For example, if you have a habit of using multiple terminals at once, you might want to enable the histappend option. Bash-specific shell options that are boolean in nature (take either on or off as a value) are typically enabled or disabled using the shopt built-in command. Bash settings that take a more complex value (for example, HISTTIMEFORMAT) tend to be configured by assigning the value to an environment variable. Customizing Bash with both shell options and environment variable is demonstrated below.
# Configure Bash History # Expand dir env vars on tab and set histappend
shopt -s direxpand histappend # - ignoreboth = ignorespace and ignoredup
HISTCONTROL='ignoreboth' # Controls the format of the time in output of `history`
HISTTIMEFORMAT="[%F %T] " # Infinite history
# NB: on newer bash, anything < 0 is the supported way, but on CentOS/RHEL
# at least, only this works
HISTSIZE=
HISTFILESIZE= # or for those of us on newer Bash
HISTSIZE=-1
HISTFILESIZE=-1
The direxpand option shown in the example above will cause Bash to replace directory names with the results of word expansion when performing filename completion. This will change the contents of the readline editing buffer, so what you typed is masked by what the completion expands it to.
The HISTCONTROL variable is used to enable or disable some filtering options for the command history. Duplicate lines, lines with leading blank spaces, or both can be filtered from the command history by configuring this setting. To quote Dusty Mabe, the engineer I got the tip from:
ignoredup makes history not log duplicate entries (if you are running a command over and over). ignorespace ignores entries with a space in the front, which is useful if you are setting an environment variable with a secret or running a command with a secret that you don’t want logged to disk. ignoreboth does both.
Dusty Mabe – Redhat Principle Software Engineer, June 19, 2020
For users who do a lot of work on the command line, Bash has the CDPATH environment variable. If CDPATH is configured with a list of directories to search, the cd command, when provided a relative path as its first argument, will check all the listed directories in order for a matching subdirectory and change to the first one found.
# .bash_profile # set CDPATH CDPATH="/var/home/username/favdir1:/var/home/username/favdir2:/var/home/username/favdir3" # or could look like this
CDPATH="/:~:/var:~/favdir1:~/favdir2:~/favdir3"
CDPATH should be updated the same way PATH is typically updated – by referencing itself on the right hand side of the assignment to preserve the previous values.
# .bash_profile # set CDPATH
CDPATH="/var/home/username/favdir1:/var/home/username/favdir2:/var/home/username/favdir3" # or could look like this
CDPATH="/:~:/var:~/favdir1:~/favdir2:~/favdir3" CDPATH="$CDPATH:~/favdir4:~/favdir5"
PATH is another very important variable. It is the search path for commands on the system. Be aware that some applications require that their own directories be included in the PATH variable to function properly. As with CDPATH, appending new values to PATH can be done by referencing the old values on the right hand side of the assignment. If you want to prepend the new values instead, simply place the old values ($PATH) at the end of the list. Note that on Fedora, the list values are separated with the colon character (:).
# .bash_profile # Add PATH values to the PATH Environment Variable
PATH="$PATH:~/bin:~:/usr/bin:/bin:~/jdk-13.0.2:~/apache-maven-3.6.3" export PATH
The command prompt is another popular candidate for customization. The command prompt has seven customizable parameters:
PROMPT_COMMAND If set, the value is executed as a command prior to issuing each primary prompt ($PS1).
PROMPT_DIRTRIM If set to a number greater than zero, the value is used as the number of trailing directory components to retain when expanding the \w and \W prompt string escapes. Characters removed are replaced with an ellipsis.
PS0 The value of this parameter is expanded like PS1 and displayed by interactive shells after reading a command and before the command is executed.
PS1 The primary prompt string. The default value is ‘\s-\v\$ ‘. …
PS2 The secondary prompt string. The default is ‘> ‘. PS2 is expanded in the same way as PS1 before being displayed.
PS3 The value of this parameter is used as the prompt for the select command. If this variable is not set, the select command prompts with ‘#? ‘
PS4 The value of this parameter is expanded like PS1 and the expanded value is the prompt printed before the command line is echoed when the -x option is set. The first character of the expanded value is replicated multiple times, as necessary, to indicate multiple levels of indirection. The default is ‘+ ‘.
Reference Documentation for Bash Edition 5.0, for Bash Version 5.0. May 2019
An entire article could be devoted to this one aspect of Bash. There are copious quantities of information and examples available. Some example dotfiles, including prompt reconfiguration, are provided in a repository linked at the end of this article. Feel free to use and experiment with the examples provided in the repository.
Conclusion
Now that you are armed with a little knowledge about how Bash works, feel free to modify your Bash dotfiles to suit your own needs and preferences. Pretty up your prompt. Go nuts making aliases. Or otherwise make your computer truly yours. Examine the content of /etc/profile, /etc/bashrc, and /etc/profile.d/ for inspiration.
Some comments about terminal emulators are fitting here. There are ways to setup your favorite terminal to behave exactly as you want. You may have already realized this, but often this modification is done with a … wait for it … dotfile in the users home directory. The terminal emulator can also be started as a login session, and some people always use login sessions. How you use your terminal, and your computer, will have a bearing on how you modify (or not) your dotfiles.
If you’re curious about what type session you are in at the command line the following script can help you determine that.
#!/bin/bash case "$-" in (*i*) echo This shell is interactive ;; (*) echo This shell is not interactive ;;
esac
Place the above in a file, mark it executable, and run it to see what type of shell you are in. $- is a variable in Bash that contains the letter i when the shell is interactive. Alternatively, you could just echo the $- variable and inspect the output for the presence of the i flag:
$ echo $-
Reference information
The below references can be consulted for more information and examples. The Bash man page is also a great source of information. Note that your local man page is guaranteed to document the features of the version of Bash you are running whereas information found online can sometimes be either too old (outdated) or too new (not yet available on your system).
Please carefully review the information provided in the above repository. Some of it may be outdated. There are many examples of not only dotfiles for Bash, but also custom scripts and pet container setups for development. I recommend starting with John Lebon’s dotfiles. They are some of the most detailed I have seen and contain very good descriptions throughout. Enjoy!
LaTeX offers a number of tools to create and customise tables, in this series we will be using the tabular and tabularx environment to create and customise tables.
Basic table
To create a table you simply specify the environment \begin{tabular}{columns}
In the above example “{c|c}” in the curly bracket refers to the position of the text in the column. The below table summarises the positional argument together with the description.
Position
Argument
c
Position text in the centre
l
Position text left-justified
r
Position text right-justified
p{width}
Align the text at the top of the cell
m{width}
Align the text in the middle of the cell
b{width}
Align the text at the bottom of the cell
Both m{width} and b{width} requires the array package to be specified in the preamble.
Using the example above, let us breakdown the important points used and describe a few more options that you will see in this series
Option
Description
&;
Defines each cell, the ampersand is only used from the second column
\
This terminates the row and start a new row
|
Specifies the vertical line in the table (optional)
\hline
Specifies the horizontal line (optional)
*{num}{form}
This is handy when you have many columns and is an efficient way of limiting the repetition
||
Specifies the double vertical line
Customizing a table
Now that some of the options available are known, let us create a table using the options described in the previous section.
Notice that the column that we want the long text to be wrapped has a capital “X” specified.
Multi-row and multi-column
There are times when you will need to merge rows and/or column. This section describes how it is accomplished. To use multi-row and multi-column add multi-row to the preamble.
Multirow
Multirow takes the following argument \multirow{number_of_rows}{width}{text}, let us look at the below example.
Colours can be assigned to the text, an individual cell or the entire row. Additionally, we can configure alternating colours for each row.
Before we can add colour to our tables we need to include \usepackage[table]{xcolor} into the preamble. We can also define colours using the following colour reference LaTeX Colour or by adding an exclamation after the colour prefixed by the shade from 0 to 100. For example, gray!30
Below example demonstrate this a table with alternate colours, \rowcolors take the following options \rowcolors{row_start_colour}{even_row_colour}{odd_row_colour}.
In addition to the above example, \rowcolor can be used to specify the colour of each row, this method works best when there are multi-rows. The following examples show the impact of using the \rowcolours with multi-row and how to work around it.
As you can see the multi-row is visible in the first row, to fix this we have to do the following.
Let us discuss the changes that were implemented to resolve the multi-row with the alternate colour issue.
The first row started above the multi-row
The number of rows was changed from 2 to -2, which means to read from the line above
\rowcolor was specified for each row, more importantly, the multi-rows must have the same colour so that you can have the desired results.
One last note on colour, to change the colour of a column you need to create a new column type and define the colour. The example below illustrates how to define the new column colour.
\newcolumntype{g}{>{\columncolor{darkblue}}l}
Let’s break it down:
\newcolumntype{g}: defines the letter g as the new column
{>{\columncolor{darkblue}}l}: here we select our desired colour, and l tells the column to be left-justified, this can be subsitued with c or r
There may be times when your table has many columns and will not fit elegantly in portrait. With the rotating package in preamble you will be able to create a sideways table. The below example demonstrates this.
For the landscape table, we will use the sidewaystable environment and add the tabular environment within it, we also specified additional options.
\centering to position the table in the centre of the page
\caption{} to give our table a name
\label{} this enables us to reference the table in our document
To include a list into a table you can use tabularx and include the list in the column where the X is specified. Another option will be to use tabular but you must specify the column width.
LaTeX offers many ways to customise your table with tabular and tabularx, you can also add both tabular and tabularx within the table environment (\begin\table) to add the table name and to position the table.
The packages used in this series are:
\usepackage{fullpage}
\usepackage{blindtext} % add demo text
\usepackage{array} % used for column positions
\usepackage{tabularx} % adds tabularx which is used for text wrapping
\usepackage{multirow} % multi-row and multi-colour support
\usepackage[table]{xcolor} % add colour to the columns \usepackage{rotating} % for landscape/sideways tables
Additional Reading
This was an intermediate lesson on tables. For more advanced information about tables and LaTex in general, you can go to the LaTeX Wiki.
NetworkManager is the network configuration daemon used on Fedora and many other distributions. It provides a consistent way to configure network interfaces and other network-related aspects on a Linux machine. Among many other features, it provides a Internet connection sharing functionality that can be very useful in different situations.
For example, suppose you are in a place without Wi-Fi and want to share your laptop’s mobile data connection with friends. Or maybe you have a laptop with broken Wi-Fi and want to connect it via Ethernet cable to another laptop; in this way the first laptop become able to reach the Internet and maybe download new Wi-Fi drivers.
In cases like these it is useful to share Internet connectivity with other devices. On smartphones this feature is called “Tethering” and allows sharing a cellular connection via Wi-Fi, Bluetooth or a USB cable.
This article shows how the connection sharing mode offered by NetworkManager can be set up easily; it addition, it explains how to configure some more advanced features for power users.
How connection sharing works
The basic idea behind connection sharing is that there is an upstream interface with Internet access and a downstream interface that needs connectivity. These interfaces can be of a different type—for example, Wi-Fi and Ethernet.
If the upstream interface is connected to a LAN, it is possible to configure our computer to act as a bridge; a bridge is the software version of an Ethernet switch. In this way, you “extend” the LAN to the downstream network. However this solution doesn’t always play well with all interface types; moreover, it works only if the upstream network uses private addresses.
A more general approach consists in assigning a private IPv4 subnet to the downstream network and turning on routing between the two interfaces. In this case, NAT (Network Address Translation) is also necessary. The purpose of NAT is to modify the source of packets coming from the downstream network so that they look as if they originate from your computer.
It would be inconvenient to configure manually all the devices in the downstream network. Therefore, you need a DHCP server to assign addresses automatically and configure hosts to route all traffic through your computer. In addition, in case the sharing happens through Wi-Fi, the wireless network adapter must be configured as an access point.
There are many tutorials out there explaining how to achieve this, with different degrees of difficulty. NetworkManager hides all this complexity and provides a shared mode that makes this configuration quick and convenient.
Configuring connection sharing
The configuration paradigm of NetworkManager is based on the concept of connection (or connection profile). A connection is a group of settings to apply on a network interface.
This article shows how to create and modify such connections using nmcli, the NetworkManager command line utility, and the GTK connection editor. If you prefer, other tools are available such as nmtui (a text-based user interface), GNOME control center or the KDE network applet.
A reasonable prerequisite to share Internet access is to have it available in the first place; this implies that there is already a NetworkManager connection active. If you are reading this, you probably already have a working Internet connection. If not, see this article for a more comprehensive introduction to NetworkManager.
The rest of this article assumes you already have a Wi-Fi connection profile configured and that connectivity must be shared over an Ethernet interface enp1s0.
To enable sharing, create a connection for interface enp1s0 and set the ipv4.method property to shared instead of the usual auto:
$ nmcli connection add type ethernet ifname enp1s0 ipv4.method shared con-name local
The shared IPv4 method does multiple things:
enables IP forwarding for the interface;
adds firewall rules and enables masquerading;
starts dnsmasq as a DHCP and DNS server.
NetworkManager connection profiles, unless configured otherwise, are activated automatically. The new connection you have added should be already active in the device status:
$ nmcli device
DEVICE TYPE STATE CONNECTION
enp1s0 ethernet connected local
wlp4s0 wifi connected home-wifi
If that is not the case, activate the profile manually with nmcli connection up local.
Changing the shared IP range
Now look at how NetworkManager configured the downstream interface enp1s0:
$ ip -o addr show enp1s0
8: enp1s0 inet 10.42.0.1/24 brd 10.42.0.255 ...
10.42.0.1/24 is the default address set by NetworkManager for a device in shared mode. Addresses in this range are also distributed via DHCP to other computers. If the range conflicts with other private networks in your environment, change it by modifying the ipv4.addresses property:
$ nmcli connection modify local ipv4.addresses 192.168.42.1/24
Remember to activate again the connection profile after any change to apply the new values:
$ nmcli connection up local $ ip -o addr show enp1s0
8: enp1s0 inet 192.168.42.1/24 brd 192.168.42.255 ...
If you prefer using a graphical tool to edit connections, install the nm-connection-editor package. Launch the program and open the connection to edit; then select the Shared to other computers method in the IPv4 Settings tab. Finally, if you want to use a specific IP subnet, click Add and insert an address and a netmask.
Adding custom dnsmasq options
In case you want to further extend the dnsmasq configuration, you can add new configuration snippets in /etc/NetworkManager/dnsmasq-shared.d/. For example, the following configuration:
tells dnsmasq to advertise a NTP server via DHCP. In addition, it assigns a static IP to a client with a certain MAC.
There are many other useful options in the dnsmasq manual page. However, remember that some of them may conflict with the rest of the configuration; so please use custom options only if you know what you are doing.
Other useful tricks
If you want to set up sharing via Wi-Fi, you could create a connection in Access Point mode, manually configure the security, and then enable connection sharing. Actually, there is a quicker way, the hotspot mode:
This does everything needed to create a functional access point with connection sharing. The interface and password options are optional; if they are not specified, nmcli chooses the first Wi-Fi device available and generates a random password. Use the ‘nmcli device wifi show-password‘ command to display information for the active hotspot; the output includes the password and a text-based QR code that you can scan with a phone:
What about IPv6?
Until now this article discussed sharing IPv4 connectivity. NetworkManager also supports sharing IPv6 connectivity through DHCP prefix delegation. Using prefix delegation, a computer can request additional IPv6 prefixes from the DHCP server. Those public routable addresses are assigned to local networks via Router Advertisements. Again, NetworkManager makes all this easier through the shared IPv6 mode:
$ nmcli connection modify local ipv6.method shared
Note that IPv6 sharing requires support from the Internet Service Provider, which should give out prefix delegations through DHCP. If the ISP doesn’t provides delegations, IPv6 sharing will not work; in such case NM will report in the journal that no prefixes are available:
policy: ipv6-pd: none of 0 prefixes of wlp1s0 can be shared on enp1s0
Also, note that the Wi-Fi hotspot command described above only enables IPv4 sharing; if you want to also use IPv6 sharing you must edit the connection manually.
Conclusion
Remember, the next time you need to share your Internet connection, NetworkManager will make it easy for you.
If you have suggestions on how to improve this feature or any other feedback, please reach out to the NM community using the mailing list, the issue tracker or joining the #nm IRC channel on freenode.
LaTeX lists are enclosed environments, and each item in the list can take a line of text to a full paragraph. There are three types of lists available in LaTeX. They are:
Itemized: unordered or bullet
Enumerated: ordered
Description: descriptive
Creating lists
To create a list, prefix each list item with the \item command. Precede and follow the list of items with the \begin{<type>} and \end{<type>} commands respectively where <type> is substituted with the type of the list as illustrated in the following examples.
\begin{description} \item[Fedora 6] Code name Zod \item[Fedora 8] Code name Werewolf
\end{description}
Spacing list items
The default spacing can be customized by adding \usepackage{enumitem} to the preamble. The enumitem package enables the noitemsep option and the \itemsep command which you can use on your lists as illustrated below.
Using the noitemsep option
Enclose the noitemsep option in square brackets and place it on the \begin command as shown below. This option removes the default spacing.
The below example illustrates each of the different itemiszed list styles.
% Itemize style
\begin{itemize} \item[$\ast$] Asterisk \item[$\diamond$] Diamond \item[$\circ$] Circle \item[$\cdot$] Period \item[$\bullet$] Bullet (default) \item[--] Dash \item[$-$] Another dash
\end{itemize}
There are three methods of setting list styles. They are illustrated below. These methods are listed by priority; highest priority first. A higher priority will override a lower priority if more than one is defined for a list item.
List styling method 1 – per item
Enclose the name of the desired style in square brackets and place it on the \item command as demonstrated below.
% First method
\begin{itemize} \item[$\ast$] Asterisk \item[$\diamond$] Diamond \item[$\circ$] Circle \item[$\cdot$] period \item[$\bullet$] Bullet (default) \item[--] Dash \item[$-$] Another dash
\end{itemize}
List styling method 2 – on the list
Prefix the name of the desired style with label=. Place the parameter, including the label= prefix, in square brackets on the \begin command as demonstrated below.
This method changes the default style for the entire document. Use the \renewcommand to set the values for the labelitems. There is a different labelitem for each of the four label depths as demonstrated below.
% Third method
\renewcommand{\labelitemi}{$\ast$}
\renewcommand{\labelitemii}{$\diamond$}
\renewcommand{\labelitemiii}{$\bullet$}
\renewcommand{\labelitemiv}{$-$}
Summary
LaTeX supports three types of lists. The style and spacing of each of the list types can be customized. More LaTeX elements will be explained in future posts.
Sharing files with Fedora 32 using Samba is cross-platform, convenient, reliable, and performant.
What is ‘Samba’?
Samba is a high-quality implementation of Server Message Block protocol (SMB). Originally developed by Microsoft for connecting windows computers together via local-area-networks, it is now extensively used for internal network communications.
In this guide we provide the minimal instructions to enable:
Public Folder Sharing (Both Read Only and Read Write)
User Home Folder Access
Note about this guide: The convention '~]$' for a local user command prompt, and '~]#' for a super user prompt will be used.
Public Sharing Folder
Having a shared public place where authenticated users on an internal network can access files, or even modify and change files if they are given permission, can be very convenient. This part of the guide walks through the process of setting up a shared folder, ready for sharing with Samba.
Please Note: This guide assumes the public sharing folder is on a Modern Linux Filesystem; other filesystems such as NTFS or FAT32 will not work. Samba uses POSIX Access Control Lists (ACLs). For those who wish to learn more about Access Control Lists, please consider reading the documentation: "Red Hat Enterprise Linux 7: System Administrator's Guide: Chapter 5. Access Control Lists", as it likewise applies to Fedora 32. In General, this is only an issue for anyone who wishes to share a drive or filesystem that was created outside of the normal Fedora Installation process. (such as a external hard drive). It is possible for Samba to share filesystem paths that do not support POSIX ACLs, however this is out of the scope of this guide.
Create Folder
For this guide the /srv/public/ folder for sharing will be used.
The /srv/ directory contains site-specific data served by a Red Hat Enterprise Linux system. This directory gives users the location of data files for a particular service, such as FTP, WWW, or CVS. Data that only pertains to a specific user should go in the /home/ directory.
Make the Folder (will provide an error if the folder already exists).
~]# mkdir --verbose /srv/public Verify folder exists:
~]$ ls --directory /srv/public Expected Output:/srv/public
Set Filesystem Security Context
To have read and write access to the public folder the public_content_rw_t security context will be used for this guide. Those wanting read only may use: public_content_t.
Label files and directories that have been created with the public_content_rw_t type to share them with read and write permissions through vsftpd. Other services, such as Apache HTTP Server, Samba, and NFS, also have access to files labeled with this type. Remember that booleans for each service must be enabled before they can write to files labeled with this type.
Now that the folder has been added to the local system’s filesystem security context registry; The restorecon command can be used to ‘restore’ the context to the folder:
Restore security context to the /srv/public folder:
$~]# restorecon -Rv /srv/public Verify security context was correctly applied:
~]$ ls --directory --context /srv/public/ Expected Output:unconfined_u:object_r:public_content_rw_t:s0 /srv/public/
User Permissions
Creating the Sharing Groups
To allow a user to either have read only, or read and write accesses to the public share folder create two new groups that govern these privileges: public_readonly and public_readwrite.
User accounts can be granted access to read only, or read and write by adding their account to the respective group (and allow login via Samba creating a smb password). This process is demonstrated in the section: “Test Public Sharing (localhost)”.
Create the public_readonly and public_readwrite groups:
~]# groupadd public_readonly
~]# groupadd public_readwrite Verify successful creation of groups:
~]$ getent group public_readonly public_readwrite Expected Output: (Note: x:1...: number will probability differ on your System)public_readonly:x:1009:
public_readwrite:x:1010:
Set Permissions
Now set the appropriate user permissions to the public shared folder:
Set User and Group Permissions for Folder:
~]# chmod --verbose 2700 /srv/public
~]# setfacl -m group:public_readonly:r-x /srv/public
~]# setfacl -m default:group:public_readonly:r-x /srv/public
~]# setfacl -m group:public_readwrite:rwx /srv/public
~]# setfacl -m default:group:public_readwrite:rwx /srv/public Verify user permissions have been correctly applied:
~]$ getfacl --absolute-names /srv/public Expected Output:file: /srv/public
owner: root
group: root
flags: -s-
user::rwx
group::---
group:public_readonly:r-x
group:public_readwrite:rwx
mask::rwx
other::---
default:user::rwx
default:group::---
default:group:public_readonly:r-x
default:group:public_readwrite:rwx
default:mask::rwx
default:other::---
Samba
Installation
~]# dnf install samba
Hostname (systemwide)
Samba will use the name of the computer when sharing files; it is good to set a hostname so that the computer can be found easily on the local network.
View Your Current Hostname:
~]$ hostnamectl status
If you wish to change your hostname to something more descriptive, use the command:
Modify your system's hostname (example):
~]# hostnamectl set-hostname "simple-samba-server"
For a more complete overview of the hostnamectl command, please read the previous Fedora Magazine Article: "How to set the hostname on Fedora".
Firewall
Configuring your firewall is a complex and involved task. This guide will just have the most minimal manipulation of the firewall to enable Samba to pass through.
Allow Samba access through the firewall:
~]# firewall-cmd --add-service=samba --permanent
~]# firewall-cmd --reload Verify Samba is included in your active firewall:
~]$ firewall-cmd --list-services Output (should include):samba
Configuration
Remove Default Configuration
The stock configuration that is included with Fedora 32 is not required for this simple guide. In particular it includes support for sharing printers with Samba.
For this guide make a backup of the default configuration and create a new configuration file from scratch.
Create a backup copy of the existing Samba Configuration:
~]# cp --verbose --no-clobber /etc/samba/smb.conf /etc/samba/smb.conf.fedora0 Empty the configuration file:
~]# > /etc/samba/smb.conf
Samba Configuration
Please Note: This configuration file does not contain any global definitions; the defaults provided by Samba are good for purposes of this guide.
Edit the Samba Configuration File with Vim:
~]# vim /etc/samba/smb.conf
Add the following to /etc/samba/smb.conf file:
# smb.conf - Samba Configuration File # The name of the share is in square brackets [],
# this will be shared as //hostname/sharename # There are a three exceptions:
# the [global] section;
# the [homes] section, that is dynamically set to the username;
# the [printers] section, same as [homes], but for printers. # path: the physical filesystem path (or device)
# comment: a label on the share, seen on the network.
# read only: disable writing, defaults to true. # For a full list of configuration options,
# please read the manual: "man smb.conf". [global] [public]
path = /srv/public
comment = Public Folder
read only = No
Write Permission
By default Samba is not granted permission to modify any file of the system. Modify system’s security configuration to allow Samba to modify any filesystem path that has the security context of public_content_rw_t.
For convenience, Fedora has a built-in SELinux Boolean for this purpose called: smbd_anon_write, setting this to true will enable Samba to write in any filesystem path that has been set to the security context of public_content_rw_t.
For those who are wishing Samba only have a read-only access to their public sharing folder, they may choose skip this step and not set this boolean.
Set SELinux Boolean allowing Samba to write to filesystem paths set with the security context public_content_rw_t:
~]# setsebool -P smbd_anon_write=1 Verify bool has been correctly set:
$ getsebool smbd_anon_write Expected Output:smbd_anon_write --> on
Samba Services
The Samba service is divided into two parts that we need to start.
Samba ‘smb’ Service
The Samba “Server Message Block” (SMB) services is for sharing files and printers over the local network.
Enable and start smb and nmb services:
~]# systemctl enable smb.service
~]# systemctl start smb.service Verify smb service:
~]# systemctl status smb.service
Test Public Sharing (localhost)
To demonstrate allowing and removing access to the public shared folder, create a new user called samba_test_user, this user will be granted permissions first to read the public folder, and then access to read and write the public folder.
The same process demonstrated here can be used to grant access to your public shared folder to other users of your computer.
The samba_test_user will be created as a locked user account, disallowing normal login to the computer.
Create 'samba_test_user', and lock the account.
~]# useradd samba_test_user
~]# passwd --lock samba_test_user Set a Samba Password for this Test User (such as 'test'):
~]# smbpasswd -a samba_test_user
Test Read Only access to the Public Share:
Add samba_test_user to the public_readonly group:
~]# gpasswd --add samba_test_user public_readonly Login to the local Samba Service (public folder):
~]$ smbclient --user=samba_test_user //localhost/public First, the ls command should succeed,
Second, the mkdir command should not work,
and finally, exit:
smb: \> ls
smb: \> mkdir error
smb: \> exit Remove samba_test_user from the public_readonly group:
gpasswd --delete samba_test_user public_readonly
Test Read and Write access to the Public Share:
Add samba_test_user to the public_readwrite group:
~]# gpasswd --add samba_test_user public_readwrite Login to the local Samba Service (public folder):
~]$ smbclient --user=samba_test_user //localhost/public First, the ls command should succeed,
Second, the mkdir command should work,
Third, the rmdir command should work,
and finally, exit:
smb: \> ls
smb: \> mkdir success
smb: \> rmdir success
smb: \> exit Remove samba_test_user from the public_readwrite group:
~]# gpasswd --delete samba_test_user public_readwrite
After testing is completed, for security, disable the samba_test_user‘s ability to login in via samba.
Disable samba_test_user login via samba:
~]# smbpasswd -d samba_test_user
Home Folder Sharing
In this last section of the guide; Samba will be configured to share a user home folder.
For example: If the user bob has been registered with smbpasswd, bob’s home directory /home/bob, would become the share //server-name/bob.
This share will only be available for bob, and no other users.
This is a very convenient way of accessing your own local files; however naturally it carries at a security risk.
Setup Home Folder Sharing
Give Samba Permission for Public Folder Sharing
Set SELinux Boolean allowing Samba to read and write to home folders:
~]# setsebool -P samba_enable_home_dirs=1 Verify bool has been correctly set:
$ getsebool samba_enable_home_dirs Expected Output:samba_enable_home_dirs --> on
Add Home Sharing to the Samba Configuration
Append the following to the systems smb.conf file:
# The home folder dynamically links to the user home. # If 'bob' user uses Samba:
# The homes section is used as the template for a new virtual share: # [homes]
# ... (various options) # A virtual section for 'bob' is made:
# Share is modified: [homes] -> [bob]
# Path is added: path = /home/bob
# Any option within the [homes] section is appended. # [bob]
# path = /home/bob
# ... (copy of various options) # here is our share,
# same as is included in the Fedora default configuration. [homes] comment = Home Directories valid users = %S, %D%w%S browseable = No read only = No inherit acls = Yes
Reload Samba Configuration
Tell Samba to reload it's configuration:
~]# smbcontrol all reload-config
Test Home Directory Sharing
Switch to samba_test_user and create a folder in it's home directory:
~]# su samba_test_user
samba_test_user:~]$ cd ~
samba_test_user:~]$ mkdir --verbose test_folder
samba_test_user:~]$ exit Enable samba_test_user to login via Samba:
~]# smbpasswd -e samba_test_user Login to the local Samba Service (samba_test_user home folder):
$ smbclient --user=samba_test_user //localhost/samba_test_user Test (all commands should complete without error):
smb: \> ls
smb: \> ls test_folder
smb: \> rmdir test_folder
smb: \> mkdir home_success
smb: \> rmdir home_success
smb: \> exit Disable samba_test_userfrom login in via Samba:
~]# smbpasswd -d samba_test_user
Python is one of the most popular and powerful programming languages available. Because it’s free and open source, it’s available to everyone — and most Fedora systems come with the language already installed. Python is useful for a wide variety of tasks, but among them is processing comma-separated value (CSV) data. CSV files often start off life as tables or spreadsheets. This article shows how to get started working with CSV data in Python 3.
CSV data is precisely what it sounds like. A CSV file includes one row of data at a time, with data values separated by commas. Each row is defined by the same fields. Short CSV files are often easily read and understood. But longer data files, or those with more fields, may be harder to parse with the naked eye, so computers work better in those cases.
Here’s a simple example where the fields are Name, Email, and Country. In this example, the CSV data includes a field definition as the first row, although that is not always the case.
Name,Email,Country
John Q. Smith,jqsmith@example.com,USA
Petr Novak,pnovak@example.com,CZ
Bernard Jones,bjones@example.com,UK
Reading CSV from spreadsheets
Python helpfully includes a csv module that has functions for reading and writing CSV data. Most spreadsheet applications, both native like Excel or Numbers, and web-based such as Google Sheets, can export CSV data. In fact, many other services that can publish tabular reports will also export as CSV (PayPal for instance).
The Python csv module has a built in reader method called DictReader that can deal with each data row as an ordered dictionary (OrderedDict). It expects a file object to access the CSV data. So if our file above is called example.csv in the current directory, this code snippet is one way to get at this data:
f = open('example.csv', 'r')
from csv import DictReader
d = DictReader(f)
data = []
for row in d: data.append(row)
Now the data object in memory is a list of OrderedDict objects :
>>> print(data[0]['Country'])
USA
>>> print(data[2]['Email'])
bjones@example.com
By the way, if you have to deal with a CSV file with no header row of field names, the DictReader class lets you define them. In the example above, add the fieldnames argument and pass a sequence of the names:
d = DictReader(f, fieldnames=['Name', 'Email', 'Country'])
A real world example
I recently wanted to pick a random winner from a long list of individuals. The CSV data I pulled from spreadsheets was a simple list of names and email addresses.
Fortunately, Python also has a helpful random module good for generating random values. The randrange function in the Random class from that module was just what I needed. You can give it a regular range of numbers — like integers — and a step value between them. The function then generates a random result, meaning I could get a random integer (or row number!) back within the total number of rows in my data.
So this small program worked well:
from csv import DictReader
from random import Random d = DictReader(open('mydata.csv'))
data = []
for row in d: data.append(row) r = Random()
winner = data[r.randrange(0, len(data), 1)]
print('The winner is:', winner['Name'])
print('Email address:', winner['Email'])
Obviously this example is extremely simple. Spreadsheets themselves include sophisticated ways to analyze data. However, if you want to do something outside the realm of your spreadsheet app, Python may be just the trick!
A network firewall is more or less what it sounds like: a protective barrier that prevents unwanted network transmissions. They are most frequently used to prevent outsiders from contacting or using network services on a system. For instance, if you’re running a laptop at school or in a coffee shop, you probably don’t want strangers poking around on it.
Every Fedora system has a firewall built in. It’s part of the network functions in the Linux kernel inside. This article shows you how to change its settings using firewall-cmd.
Network basics
This article can’t teach you everything about computer networks. But a few basics suffice to get you started.
Any computer on a network has an IP address. Think of this just like a mailing address that allows correct routing of data. Each computer also has a set of ports, numbered 0-65535. These are not physical ports; instead, you can think of them as a set of connection points at the address.
In many cases, the port is a standard number or range depending on the application expected to answer. For instance, a web server typically reserves port 80 for non-secure HTTP communications, and/or 443 for secure HTTPS. The port numbers under 1024 are reserved for system and well-known purposes, ports 1024-49151 are registered, and ports 49152 and above are usually ephemeral (used only for a short time).
Each of the two most common protocols for Internet data transfer, TCP and UDP, have this set of ports. TCP is used when it’s important that all data be received and, if it arrives out of order, reassembled in the right order. UDP is used for more time-sensitive services that can withstand losing some data.
An application running on the system, such as a web server, reserves one or more ports (as seen above, 80 and 443 for example). Then during network communication, a host establishes a connection between a source address and port, and the destination address and port.
A network firewall can block or permit transmissions of network data based on rules like address, port, or other criteria. The firewall-cmd utility lets you interact with the rule set to view or change how the firewall works.
Firewall zones
To verify the firewall is running, use this command with sudo. (In fairness, you can run firewall-cmd without the sudo command in environments where PolicyKit is running.)
$ sudo firewall-cmd --state running
The firewalld service supports any number of zones. Each zone can have its own settings and rules for protection. In addition, each network interface can be placed in any zone individually The default zone for an external facing interface (like the wifi or wired network card) on a Fedora Workstation is the FedoraWorkstation zone.
To see what zones are active, use the –get-active-zones flag. On this system, there are two network interfaces, a wired Ethernet card wlp2s0 and a virtualization (libvirt) bridge interface virbr0:
To see the default zone, or all the defined zones:
$ sudo firewall-cmd --get-default-zone
FedoraWorkstation
$ sudo firewall-cmd --get-zones
FedoraServer FedoraWorkstation block dmz drop external home internal libvirt public trusted work
To see the services the firewall is allowing other systems to access in the default zone, use the –list-services flag. Here is an example from a customized system; you may see something different.
This system has four services exposed. Each of these has a well-known port number. The firewall recognizes them by name. For instance, the ssh service is associated with port 22.
To see other port settings for the firewall in the current zone, use the –list-ports flag. By the way, you can always declare the zone you want to check:
This shows that ports 1025 and above (both UDP and TCP) are open by default.
Changing zones, ports, and services
The above setting is a design decision.* It ensures novice users can use network facing applications they install. If you know what you’re doing and want a more protective default, you can move the interface to the FedoraServer zone, which prohibits any ports not explicitly allowed. (Warning: if you’re using the host via the network, you may break your connection — meaning you’ll have to go to that box physically to make further changes!)
* This article is not the place to discuss that decision, which went through many rounds of review and debate in the Fedora community. You are welcome to change settings as needed.
If you want to open a well-known port that belongs to a service, you can add that service to the default zone (or use –zone to adjust a different zone). You can add more than one at once. This example opens up the well-known ports for your web server for both HTTP and HTTPS traffic, on ports 80 and 443:
Not all services are defined, but many are. To see the whole list, use the –get-services flag.
If you want to add specific ports, you can do that by number and protocol as well. (You can also combine –add-service and –add-port flags, as many as necessary.) This example opens up the UDP service for a network boot service:
$ sudo firewall-cmd --add-port=67/udp
success
Important: If you want your changes to be effective after you reboot your system or restart the firewalld service, you must add the –permanent flag to your commands. The examples here only change the firewall until one of those events next happens.
These are just some of the many functions of the firewall-cmd utility and the firewalld service. There is much more information on firewalld at the project’s home page that’s worth reading and trying out.
There are plenty of cloud services available where you can store important documents. Google Drive is undoubtedly one of the most popular. It offers a matching set of applications like Docs, Sheets, and Slides to create content. But you can also store arbitrary content in your Google Drive. This article shows you how to connect it to your Fedora Workstation.
Adding an account
Fedora Workstation lets you add an account either after installation during first startup, or at any time afterward. To add your account during first startup, follow the prompts. Among them is a choice of accounts you can add:
Select Google and a login prompt appears for you to login, so use your Google account information.
Be aware this information is only transmitted to Google, not to the GNOME project. The next screen asks you to grant access, which is required so your system’s desktop can interact with Google. Scroll down to review the access requests, and choose Allow to proceed.
You can expect to receive notifications on mobile devices and Gmail that a new device — your system — accessed your Google account. This is normal and expected.
If you didn’t do this at first startup, or you need to re-add your account, open the Settings tool, and select Online Accounts to add the account. The Settings tool is available through the dropdown at right side of the Top Bar (the “gear” icon), or by opening the Overview and typing settings. Then proceed as described above.
Using the Files app with Google Drive
Open the Files app (formerly known as nautilus). Locations the Files app can access appear on the left side. Locate your Google account in the list.
When you select this account, the Files app shows the contents of your Google drive. Some files can be opened using your Fedora Workstation local apps, such as sound files or LibreOffice-compatible files (including Microsoft Office docs). Other files, such as Google app files like Docs, Sheets, and Slides, open using your web browser and the corresponding app.
Remember that if the file is large, it will take some time to receive over the network so you can open it.
You can also copy and paste files in your Google Drive storage from or to other storage connected to your Fedora Workstation. You can also use the built in functions to rename files, create folders, and organize them.
Be aware that the Files app does not refresh contents in real time. If you add or remove files from other Google connected devices like your mobile phone or tablet, you may need to hit Ctrl+R to refresh the Files app view.