https://wiki.archlinux.org/api.php?action=feedcontributions&user=Altercation&feedformat=atomArchWiki - User contributions [en]2024-03-29T02:20:30ZUser contributionsMediaWiki 1.41.0https://wiki.archlinux.org/index.php?title=Sshguard&diff=571450Sshguard2019-04-17T16:44:22Z<p>Altercation: /* firewalld */ firewallctl format of firewalld commands is now deprecated and no longer functional. replaced with correct firewall-cmd format command.</p>
<hr />
<div>[[Category:Secure Shell]]<br />
[[Category:Firewalls]]<br />
[[es:Sshguard]]<br />
[[ja:Sshguard]]<br />
{{Related articles start}}<br />
{{Related|fail2ban}}<br />
{{Related|ssh}}<br />
{{Related articles end}}<br />
{{warning|Using an IP blacklist will stop trivial attacks but it relies on an additional daemon and successful logging (the partition containing /var can become full, especially if an attacker is pounding on the server). Additionally, with the knowledge of your IP address, the attacker can send packets with a spoofed source header and get you locked out of the server. [[SSH keys]] provide an elegant solution to brute forcing without these problems.}}<br />
[http://www.sshguard.net sshguard] is a daemon that protects [[SSH]] and other services against brute-force attacks, similar to [[fail2ban]].<br />
<br />
sshguard is different from the latter in that it is written in C, is lighter and simpler to use with fewer features while performing its core function equally well.<br />
<br />
sshguard is not vulnerable to most (or maybe any) of the log analysis [https://web.archive.org/web/20120625102244/http://www.ossec.net/main/attacking-log-analysis-tools vulnerabilities] that have caused problems for similar tools.<br />
<br />
==Installation==<br />
[[Install]] the {{Pkg|sshguard}} package.<br />
<br />
==Setup==<br />
<br />
sshguard works by monitoring {{ic|/var/log/auth.log}}, syslog-ng or the [[systemd journal]] for failed login attempts. For each failed attempt, the offending host is banned from further communication for a limited amount of time. The default amount of time the offender is banned starts at 120 seconds, and is increases by a factor of 1.5 every time it fails another login. sshguard can be configured to permanently ban a host with too many failed attempts.<br />
<br />
Both temporary and permanent bans are done by adding an entry into the "sshguard" chain in iptables that drops all packets from the offender. The ban is then logged to syslog and ends up in {{ic|/var/log/auth.log}}, or the systemd journal if the latter is being used.<br />
<br />
You must configure one of the following firewalls to be used with sshguard in order for blocking to work. <br />
<br />
==== firewalld ====<br />
<br />
sshguard can work with [[firewalld]]. Make sure you have firewalld enabled, configured and setup first. To make sshguard write to your zone of preference, issue the following commands:<br />
<br />
# firewall-cmd --permanent --zone=public --add-rich-rule="rule source ipset=sshguard4 drop"<br />
<br />
If you use ipv6, you can issue the same command but substitute sshguard4 with sshguard6. Finish with<br />
<br />
# firewall-cmd --reload<br />
<br />
You can verify the above with<br />
<br />
# firewall-cmd --info-ipset=sshguard4<br />
<br />
Finally, in /etc/sshguard.conf, find the line for BACKEND and change it as follows<br />
<br />
BACKEND="/usr/lib/sshguard/sshg-fw-firewalld"<br />
<br />
==== UFW ====<br />
<br />
If UFW is installed and enabled, it must be given the ability to pass along DROP control to sshguard. This is accomplished by modifying {{ic|/etc/ufw/before.rules}} to contain the following lines which should be inserted just after the section for loopback devices. {{Note|Users running sshd on a non-standard port should substitute that in the final line above (where 22 is the standard).}}<br />
<br />
{{hc|/etc/ufw/before.rules|<br />
# allow all on loopback<br />
-A ufw-before-input -i lo -j ACCEPT<br />
-A ufw-before-output -o lo -j ACCEPT<br />
<br />
# hand off control for sshd to sshguard<br />
:sshguard - [0:0]<br />
-A ufw-before-input -p tcp --dport 22 -j sshguard<br />
}}<br />
<br />
[[Restart]] ufw after making this modification.<br />
<br />
==== iptables ====<br />
<br />
{{Note|See [[iptables]] and [[Simple stateful firewall]] first to set up a firewall.}}<br />
<br />
The main configuration required is creating a chain named {{ic|sshguard}}, where sshguard automatically inserts rules to drop packets coming from bad hosts:<br />
# iptables -N sshguard<br />
<br />
Then add a rule to jump to the {{ic|sshguard}} chain from the {{ic|INPUT}} chain. This rule must be added '''before''' any other rules processing the ports that sshguard is protecting. Use the following line to protect FTP and SSH or see [http://www.sshguard.net/docs/setup/#netfilter-iptables this documentation] for more examples.<br />
# iptables -A INPUT -m multiport -p tcp --destination-ports 21,22 -j sshguard<br />
<br />
To save the rules:<br />
# iptables-save > /etc/iptables/iptables.rules<br />
<br />
{{Note|For IPv6, repeat the same steps with ''ip6tables'' and save the rules with ''ip6tables-save'' to {{ic|/etc/iptables/ip6tables.rules}}.}}<br />
<br />
==== nftables ====<br />
<br />
Edit {{ic|/etc/sshguard.conf}} and change the value of {{ic|BACKEND}} to the following:<br />
<br />
{{hc|1=/etc/sshguard.conf|2=<br />
BACKEND="/usr/lib/sshguard/sshg-fw-nft-sets"<br />
}}<br />
<br />
Additionally you will need to [[edit]] the {{ic|sshguard.service}} so that [[iptables]] is not run:<br />
<br />
[Service]<br />
ExecStartPre= <br />
<br />
When you [[start/enable]] the {{ic|sshguard.service}}, two new tables named {{ic|sshguard}} in the {{ic|ip}} and {{ic|ip6}} address families are added which filter incoming traffic through sshguard's list of IP addresses. The chains in the {{ic|sshguard}} table have a priority of -10 and will be processed before other rules of lower priority. See {{man|7|sshguard-setup}} and [[nftables]] for more information.<br />
<br />
==Usage==<br />
<br />
===systemd===<br />
<br />
[[Enable]] and [[start]] {{ic|sshguard.service}}.<br />
<br />
===syslog-ng===<br />
If you have {{Pkg|syslog-ng}} installed, you may start sshguard directly from the command line instead.<br />
<br />
/usr/sbin/sshguard -l /var/log/auth.log -b /var/db/sshguard/blacklist.db<br />
<br />
==Configuration==<br />
<br />
Configuration is done in {{ic|/etc/sshguard.conf}} which is required for ''sshguard'' to start. A commented example is located at {{ic|/usr/share/doc/sshguard/sshguard.conf.sample}}.<br />
<br />
{{Note|Piped commands and runtime flags in ''sshguard's'' systemd units [https://sourceforge.net/p/sshguard/mailman/message/35709860/ are not supported]. Such flags can be modified in the configuration file.}}<br />
<br />
===Blacklisting threshold===<br />
<br />
By default in the Arch-provided configuration file, offenders become permanently banned once they reach a "danger" level of 120 (or 12 failed logins; see [https://www.sshguard.net/docs/terminology/#attack-dangerousness attack dangerousness] for more details). This behavior can be modified by prepending a danger level to the blacklist file.<br />
<br />
BLACKLIST_FILE=200:/var/db/sshguard/blacklist.db<br />
<br />
The {{ic|200:}} in this example tells sshguard to permanently ban a host after achieving a danger level of 200.<br />
<br />
Finally [[restart]] {{ic|sshguard.service}}<br />
<br />
===Moderate banning example===<br />
<br />
A slightly more aggressive banning rule than the default one is proposed here to illustrate various options:<br />
* It monitors [[sshd]] and [[vsftpd]] via logs from the [[systemd/Journal]]<br />
* It blocks attackers after 2 attempts (each having a cost of 10, explaining the {{ic|20}} value of the {{ic|THRESHOLD}} parameter) for 180 seconds with subsequent block time longer by a factor of 1.5. Note that this 1.5 multiplicative delay is internal and not controlled in the settings<br />
* Attackers are permanently blacklisted after 10 attempts (10 attempts having each a cost of 10, explaining the {{ic|100}} value in the {{ic|BLACKLIST_FILE}} parameter)<br />
* It blocks not only the attacker's IP but all the IPv4 subnet 24 ([[wikipedia:Classless_Inter-Domain_Routing|CIDR]] notation)<br />
<br />
{{hc|/etc/sshguard.conf|2=<br />
# Full path to backend executable (required, no default)<br />
BACKEND="/usr/lib/sshguard/sshg-fw-iptables"<br />
<br />
# Log reader command (optional, no default)<br />
LOGREADER="LANG=C /usr/bin/journalctl -afb -p info -n1 -t sshd -t vsftpd -o cat"<br />
<br />
# How many problematic attempts trigger a block<br />
THRESHOLD=20<br />
# Blocks last at least 180 seconds<br />
BLOCK_TIME=180<br />
# The attackers are remembered for up to 3600 seconds<br />
DETECTION_TIME=3600<br />
<br />
# Blacklist threshold and file name<br />
BLACKLIST_FILE=100:/var/db/sshguard/blacklist.db<br />
<br />
# IPv6 subnet size to block. Defaults to a single address, CIDR notation. (optional, default to 128)<br />
IPV6_SUBNET=64<br />
# IPv4 subnet size to block. Defaults to a single address, CIDR notation. (optional, default to 32)<br />
IPV4_SUBNET=24<br />
}}<br />
<br />
===Aggressive banning===<br />
<br />
For some users under constant attack, a more aggressive banning policy can be adopted. If you are confident that accidental failed logins are unlikely, you can instruct SSHGuard to permanently ban hosts after a single failed login. Modify the parameters in the configuration file in the following way:<br />
THRESHOLD=10<br />
BLACKLIST_FILE=10:/var/db/sshguard/blacklist.db<br />
<br />
Finally [[restart]] {{ic|sshguard.service}}.<br />
<br />
Also, to prevent multiple authentication attempts during a single connection, you may want to change {{ic|/etc/ssh/sshd_config}} by defining:<br />
MaxAuthTries 1<br />
<br />
[[Restart]] {{ic|sshd.service}} for this change to take effect.<br />
<br />
==Tips and Tricks==<br />
<br />
=== Unbanning ===<br />
<br />
If you ban ''yourself'', you can wait to get unbanned automatically or use iptables or nftables to unban yourself.<br />
<br />
==== iptables ====<br />
<br />
First check if your IP is banned by sshguard:<br />
# iptables --list sshguard --line-numbers --numeric<br />
<br />
Then use the following command to unban, with the line-number as identified in the former command: <br />
# iptables --delete sshguard ''line-number''<br />
<br />
You will also need to remove the IP address from {{ic|/var/db/sshguard/blacklist.db}} in order to make unbanning persistent.<br />
<br />
==== nftables ====<br />
<br />
Remove your IP address from the {{ic|attackers}} set:<br />
<br />
# nft delete element ''family'' sshguard attackers { ''ip_address'' }<br />
<br />
where {{ic|''family''}} is either {{ic|ip}} or {{ic|ip6}}.<br />
<br />
=== Logging ===<br />
<br />
To see what is being passed to sshguard, examine the script in {{ic|/usr/lib/systemd/scripts/sshguard-journalctl}} and the systemd service {{ic|sshguard.service}}. An equivalent command to view the logs in the terminal:<br />
<br />
$ journalctl -afb -p info SYSLOG_FACILITY=4 SYSLOG_FACILITY=10</div>Altercationhttps://wiki.archlinux.org/index.php?title=Talk:Btrfs&diff=471207Talk:Btrfs2017-03-18T21:26:36Z<p>Altercation: add proposal to add lzo compression warning</p>
<hr />
<div>{{Note|The name of the file system does not seem to have an official capitalization, so the rule for the ArchWiki has been arbitrarily set to use "Btrfs" (capital "B" and the rest lower-case); "btrfs" and "BTRFS" are therefore wrong spellings in this wiki. -- [[User:Kynikos|Kynikos]] ([[User talk:Kynikos|talk]]) 09:36, 6 January 2014 (UTC)}}<br />
<br />
== Proposal to add lzo compression warning ==<br />
The [https://wiki.debian.org/Btrfs Debian btrfs page] has a warning about compress=lzo being possibly dangerous, citing the [https://www.spinics.net/lists/linux-btrfs/msg56563.html thread here]. I propose adding a warning section that simply notes this possibility and cites either the Debian wiki, the linked thread, or both. -- [[User:altercation|altercation]]<br />
<br />
== Things to do ==<br />
<br />
Here are some items that seem to need addressing on this article. I am working on various parts of it at the moment.<br />
# Reflow headings:<br />
## Goals: [[Effective_Use_of_Headers#Use_of_headers_and_headings]]<br />
### Helpful ideas:<br />
#### [[Effective_Use_of_Headers#False_multi-level_structure]]<br />
##### Side-note<br />
##### Auxiliary information<br />
#### [[Effective_Use_of_Headers#Multi-level_structure]]<br />
##### Group arguments<br />
##### Alternative arguments<br />
##### Contradictory arguments<br />
#### [[Effective_Use_of_Headers#The_header_text]]<br />
#### [[Article_Naming_Guidelines]]<br />
##### Specificity, "Descriptivity," Brevity, "Expandibility," <br />
### See [https://btrfs.wiki.kernel.org/index.php/Main_Page Btrfs Wiki] for ideas.<br />
### See [[Beginners' Guide]] for ideas.<br />
## Proposed changes<br />
### "Installation" -> "'''Preparation'''"<br />
#### New -> "'''System Requirements'''"<br />
#### Remove -> "Additional packages"<br />
##### Move -> links to "See also" or "Related".<br />
#### "Partitioning" -> "'''Prepare the storage drive'''"<br />
##### '''OR:''' "Partitioning" (as a child) -> "'''''Choose a partition scheme'''''"<br />
### New -> "'''Create file systems'''"<br />
#### "Creating a new file system" -> "'''New file systems'''"<br />
##### "'''Examples'''"<br />
###### New -> "'''Single-drive file systems'''"<br />
###### "Multi-device filesystem and RAID feature" -> "'''Multi-drive file systems'''"<br />
####### Reduce content, provide links to "Btrfs Wiki" instead.<br />
#### "Convert from Ext3/4" -> "'''Convert existing file system'''"<br />
### New -> "'''Configuring the file system'''"<br />
#### '''OR:''' Move -> "'''Tips and tricks'''"<br />
#### Move -> "'''Mount options'''"<br />
##### "Copy-On-Write (CoW)" -> "'''Copy-on-write'''"<br />
###### "Checkpoint Interval" -> '''Merge'''<br />
##### Move -> "'''Compression'''"<br />
#### New -> "'''Skinny extents'''"<br />
#### Move -> "'''Sub-volumes'''"<br />
#### New -> "'''Quotas'''"<br />
### New -> "'''File system management'''"<br />
#### Move -> "'''Balance'''"<br />
#### Move -> "'''Defragmentation'''"<br />
#### Move -> "'''Display used/free space'''"<br />
#### Move -> "'''Balance'''"<br />
#### Move -> "'''Snapshots'''"<br />
### Move -> "'''Tips and tricks'''"<br />
### New -> "'''Troubleshooting'''"<br />
#### Move -> "'''Encryption'''"<br />
#### Move -> "'''GRUB'''"<br />
#### Move -> "'''Swap file'''"<br />
#### New -> "'''Btrfsck'''"<br />
##### See -> https://bbs.archlinux.org/viewtopic.php?id=156100<br />
### Move -> "'''See also'''"<br />
<br />
Edits:<br />
[[User:AdamT|AdamT]] ([[User_talk:AdamT|Talk]]) 08:27, 28 November 2013 (UTC);<br />
[[User:AdamT|AdamT]] ([[User_talk:AdamT|Talk]]) 04:03, 29 November 2013 (UTC);<br />
[[User:AdamT|AdamT]] ([[User_talk:AdamT|Talk]]) 04:10, 29 November 2013 (UTC);<br />
[[User:AdamT|AdamT]] ([[User_talk:AdamT|Talk]]) 02:35, 4 December 2013 (UTC)<br />
<br />
: I hope to get to this soon if there are no objections or comments. [[User:AdamT|AdamT]] ([[User_talk:AdamT|Talk]]) 20:09, 4 January 2014 (UTC)<br />
<br />
:: I believe all of his has been addressed except for quotas. -- [[User:Rdeckard|Rdeckard]] ([[User_talk:Rdeckard|talk]]) 17:27, 25 July 2016 (UTC)<br />
<br />
== "Displaying used/free space" needs rewrite ==<br />
<br />
Section "Displaying used/free space" needs a rewrite. I will hopefully do that when I have time.<br />
* The example with /usr/bin/df is misleading (on simple setups it's reporting disk usage ('used' value) quite accurate).<br />
* "btrfs filesystem usage" should be mentioned on top<br />
* there should be a link to https://btrfs.wiki.kernel.org/index.php/FAQ#How_much_free_space_do_I_have.3F<br />
<br />
{{unsigned|03:28, 17 November 2016|Mearon}}</div>Altercationhttps://wiki.archlinux.org/index.php?title=User:Altercation/Bullet_Proof_i3_Install&diff=466491User:Altercation/Bullet Proof i3 Install2017-01-24T06:44:42Z<p>Altercation: </p>
<hr />
<div>Getting i3 up and running is just the beginning. Unlike a more "heavyweight" and complete desktop environment like Gnome (which I like), tiling window managers are missing a lot of what makes using a computer "seamless". For example, disks probably won't mount automatically, wifi won't come up on its own, etc. Power users will each have their own preferences about what should be done automatically. Sometimes I prefer wifi not scanning every network out there. I may leave that off, but may choose to automount drives I connect to the system. Making these choices means building up your own desktop environment, with a tiling window manager (and linux) at the core.<br />
<br />
display manager or xinitrc<br />
(sddm or nothing at all, though if nothing I need to see what I'm missing)<br />
<br />
using .xprofile or /etc/xprofile<br />
<br />
Power<br />
https://aur.archlinux.org/packages/aclidswitch-git/<br />
tlp, etc.<br />
<br />
xmodmap<br />
<br />
https://wiki.archlinux.org/index.php/Lemonbar<br />
<br />
dmenu<br />
http://dmwit.com/yeganesh/<br />
https://github.com/vicfryzel/xmonad-config<br />
<br />
rofi<br />
<br />
unclutter (there is a rewrite of unclutter in aur that i'm using)<br />
<br />
Networking & Wifi:<br />
sudo pacman -S networkmanager network-manager-applet dhclient<br />
https://aur.archlinux.org/packages/networkmanager-dmenu-git/<br />
# systemctl enable NetworkManager<br />
<br />
make sure there is a polkit agent installed as well:<br />
https://wiki.archlinux.org/index.php/Polkit#Authentication_agents<br />
# pacman -S polkit-gnome<br />
and we need gnome-keyring<br />
# pacman -S gnome-keyring<br />
add<br />
<br />
/usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1 &<br />
<br />
to .xinitrc / .xprofile / i3 config or other<br />
<br />
for dmenu NetworkManager config:<br />
To customize dmenu, copy /usr/share/doc/networkmanager-dmenu-git/config.ini.example into ~/.config/networkmanager-dmenu/config.ini and edit:<br />
<br />
<br />
Desktop Entries<br />
consider installing dex and then adding "dex -a" for autostarting autostart desktop entries... 'dex -ad' will show dry run of which entries those are and you can instead run them manually.<br />
<br />
<br />
Libnotify<br />
<br />
Install a notification server. Probably one of dunst, statnot, twmn<br />
<br />
VPNs<br />
<br />
Status bar<br />
<br />
Shortcuts<br />
<br />
Fonts<br />
<br />
Colors<br />
<br />
Alerts<br />
<br />
Launching<br />
<br />
Appearance<br />
<br />
GTK theme, fonts<br />
<br />
Printing<br />
<br />
zero config networking<br />
<br />
firewall<br />
<br />
screen lock<br />
<br />
i3lock (custom colors version with blur)<br />
https://aur.archlinux.org/packages/xss-lock-git/ to activate lock automatically on suspend/dpms<br />
same author has https://bitbucket.org/raymonad/xss-inhibit/overview<br />
<br />
what gdm gives you<br />
<br />
session mgmt<br />
<br />
polkit<br />
<br />
infinality<br />
yes to this and using infinality repos<br />
<br />
screensaver, screen locking<br />
either<br />
sxlock<br />
i3lock-fancy<br />
xss-lock (maybe with one of the above)<br />
cf https://wiki.archlinux.org/index.php/List_of_applications/Security#Screen_lockers<br />
<br />
udisks2 plus opt dependecies (for automounting)<br />
Optional dependencies for udisks2<br />
parted: partition management<br />
gptfdisk: GUID partition table support [installed]<br />
ntfs-3g: NTFS filesystem management support<br />
dosfstools: VFAT filesystem management support [installed]<br />
https://wiki.archlinux.org/index.php/Udisks<br />
https://wiki.archlinux.org/index.php/General_troubleshooting#Session_permissions</div>Altercationhttps://wiki.archlinux.org/index.php?title=User:Altercation/Bullet_Proof_i3_Install&diff=466490User:Altercation/Bullet Proof i3 Install2017-01-24T06:36:10Z<p>Altercation: </p>
<hr />
<div>Getting i3 up and running is just the beginning. Unlike a more "heavyweight" and complete desktop environment like Gnome (which I like), tiling window managers are missing a lot of what makes using a computer "seamless". For example, disks probably won't mount automatically, wifi won't come up on its own, etc. Power users will each have their own preferences about what should be done automatically. Sometimes I prefer wifi not scanning every network out there. I may leave that off, but may choose to automount drives I connect to the system. Making these choices means building up your own desktop environment, with a tiling window manager (and linux) at the core.<br />
<br />
display manager or xinitrc<br />
(sddm or nothing at all, though if nothing I need to see what I'm missing)<br />
<br />
using .xprofile or /etc/xprofile<br />
<br />
Power<br />
https://aur.archlinux.org/packages/aclidswitch-git/<br />
tlp, etc.<br />
<br />
xmodmap<br />
<br />
https://wiki.archlinux.org/index.php/Lemonbar<br />
<br />
dmenu<br />
http://dmwit.com/yeganesh/<br />
https://github.com/vicfryzel/xmonad-config<br />
<br />
rofi<br />
<br />
unclutter (there is a rewrite of unclutter in aur that i'm using)<br />
<br />
Networking & Wifi:<br />
sudo pacman -S networkmanager network-manager-applet dhclient<br />
https://aur.archlinux.org/packages/networkmanager-dmenu-git/<br />
# systemctl enable NetworkManager<br />
<br />
make sure there is a polkit agent installed as well:<br />
https://wiki.archlinux.org/index.php/Polkit#Authentication_agents<br />
# pacman -S polkit-gnome<br />
and we need gnome-keyring<br />
# pacman -S gnome-keyring<br />
add<br />
<br />
/usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1 &<br />
<br />
to .xinitrc / .xprofile / i3 config or other<br />
<br />
for dmenu NetworkManager config:<br />
To customize dmenu, copy /usr/share/doc/networkmanager-dmenu-git/config.ini.example into ~/.config/networkmanager-dmenu/config.ini and edit:<br />
<br />
<br />
Desktop Entries<br />
consider installing dex and then adding "dex -a" for autostarting autostart desktop entries... 'dex -ad' will show dry run of which entries those are and you can instead run them manually.<br />
<br />
<br />
Libnotify<br />
<br />
Install a notification server. Probably one of dunst, statnot, twmn<br />
<br />
VPNs<br />
<br />
Status bar<br />
<br />
Shortcuts<br />
<br />
Fonts<br />
<br />
Colors<br />
<br />
Alerts<br />
<br />
Launching<br />
<br />
Appearance<br />
<br />
GTK theme, fonts<br />
<br />
Printing<br />
<br />
zero config networking<br />
<br />
firewall<br />
<br />
screen lock<br />
<br />
i3lock (custom colors version with blur)<br />
https://aur.archlinux.org/packages/xss-lock-git/ to activate lock automatically on suspend/dpms<br />
same author has https://bitbucket.org/raymonad/xss-inhibit/overview<br />
<br />
what gdm gives you<br />
<br />
session mgmt<br />
<br />
polkit<br />
<br />
infinality<br />
yes to this and using infinality repos<br />
<br />
screensaver, screen locking<br />
either<br />
sxlock<br />
i3lock-fancy<br />
xss-lock (maybe with one of the above)<br />
cf https://wiki.archlinux.org/index.php/List_of_applications/Security#Screen_lockers<br />
<br />
udisks2 plus opt dependecies (for automounting)<br />
Optional dependencies for udisks2<br />
parted: partition management<br />
gptfdisk: GUID partition table support [installed]<br />
ntfs-3g: NTFS filesystem management support<br />
dosfstools: VFAT filesystem management support [installed]<br />
https://wiki.archlinux.org/index.php/Udisks</div>Altercationhttps://wiki.archlinux.org/index.php?title=User:Altercation/Bullet_Proof_i3_Install&diff=466489User:Altercation/Bullet Proof i3 Install2017-01-24T06:34:29Z<p>Altercation: </p>
<hr />
<div>Getting i3 up and running is just the beginning. Unlike a more "heavyweight" and complete desktop environment like Gnome (which I like), tiling window managers are missing a lot of what makes using a computer "seamless". For example, disks probably won't mount automatically, wifi won't come up on its own, etc. Power users will each have their own preferences about what should be done automatically. Sometimes I prefer wifi not scanning every network out there. I may leave that off, but may choose to automount drives I connect to the system. Making these choices means building up your own desktop environment, with a tiling window manager (and linux) at the core.<br />
<br />
display manager or xinitrc<br />
(sddm or nothing at all, though if nothing I need to see what I'm missing)<br />
<br />
using .xprofile or /etc/xprofile<br />
<br />
Power<br />
https://aur.archlinux.org/packages/aclidswitch-git/<br />
tlp, etc.<br />
<br />
xmodmap<br />
<br />
https://wiki.archlinux.org/index.php/Lemonbar<br />
<br />
dmenu<br />
http://dmwit.com/yeganesh/<br />
https://github.com/vicfryzel/xmonad-config<br />
<br />
rofi<br />
<br />
unclutter (there is a rewrite of unclutter in aur that i'm using)<br />
<br />
Networking & Wifi:<br />
sudo pacman -S networkmanager network-manager-applet dhclient<br />
https://aur.archlinux.org/packages/networkmanager-dmenu-git/<br />
# systemctl enable NetworkManager<br />
<br />
make sure there is a polkit agent installed as well:<br />
https://wiki.archlinux.org/index.php/Polkit#Authentication_agents<br />
# pacman -S polkit-gnome<br />
and we need gnome-keyring<br />
# pacman -S gnome-keyring<br />
add<br />
<br />
/usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1 &<br />
<br />
to .xinitrc / .xprofile / i3 config or other<br />
<br />
for dmenu NetworkManager config:<br />
To customize dmenu, copy /usr/share/doc/networkmanager-dmenu-git/config.ini.example into ~/.config/networkmanager-dmenu/config.ini and edit:<br />
<br />
<br />
Desktop Entries<br />
consider installing dex and then adding "dex -a" for autostarting autostart desktop entries... 'dex -ad' will show dry run of which entries those are and you can instead run them manually.<br />
<br />
<br />
Libnotify<br />
<br />
Install a notification server. Probably one of dunst, statnot, twmn<br />
<br />
VPNs<br />
<br />
Status bar<br />
<br />
Shortcuts<br />
<br />
Fonts<br />
<br />
Colors<br />
<br />
Alerts<br />
<br />
Launching<br />
<br />
Appearance<br />
<br />
GTK theme, fonts<br />
<br />
Printing<br />
<br />
zero config networking<br />
<br />
firewall<br />
<br />
screen lock<br />
<br />
i3lock (custom colors version with blur)<br />
https://aur.archlinux.org/packages/xss-lock-git/ to activate lock automatically on suspend/dpms<br />
same author has https://bitbucket.org/raymonad/xss-inhibit/overview<br />
<br />
what gdm gives you<br />
<br />
session mgmt<br />
<br />
polkit<br />
<br />
infinality<br />
yes to this and using infinality repos<br />
<br />
screensaver, screen locking<br />
either<br />
sxlock<br />
i3lock-fancy<br />
xss-lock (maybe with one of the above)<br />
cf https://wiki.archlinux.org/index.php/List_of_applications/Security#Screen_lockers<br />
<br />
udisks2 plus opt dependecies (for automounting)<br />
Optional dependencies for udisks2<br />
parted: partition management<br />
gptfdisk: GUID partition table support [installed]<br />
ntfs-3g: NTFS filesystem management support<br />
dosfstools: VFAT filesystem management support [installed]</div>Altercationhttps://wiki.archlinux.org/index.php?title=User:Altercation/Bullet_Proof_i3_Install&diff=462029User:Altercation/Bullet Proof i3 Install2017-01-09T05:54:20Z<p>Altercation: </p>
<hr />
<div>Getting i3 up and running is just the beginning. Unlike a more "heavyweight" and complete desktop environment like Gnome (which I like), tiling window managers are missing a lot of what makes using a computer "seamless". For example, disks probably won't mount automatically, wifi won't come up on its own, etc. Power users will each have their own preferences about what should be done automatically. Sometimes I prefer wifi not scanning every network out there. I may leave that off, but may choose to automount drives I connect to the system. Making these choices means building up your own desktop environment, with a tiling window manager (and linux) at the core.<br />
<br />
display manager or xinitrc<br />
(sddm or nothing at all, though if nothing I need to see what I'm missing)<br />
<br />
using .xprofile or /etc/xprofile<br />
<br />
Power<br />
https://aur.archlinux.org/packages/aclidswitch-git/<br />
tlp, etc.<br />
<br />
xmodmap<br />
<br />
https://wiki.archlinux.org/index.php/Lemonbar<br />
<br />
dmenu<br />
http://dmwit.com/yeganesh/<br />
https://github.com/vicfryzel/xmonad-config<br />
<br />
rofi<br />
<br />
unclutter (there is a rewrite of unclutter in aur that i'm using)<br />
<br />
Networking & Wifi:<br />
sudo pacman -S networkmanager network-manager-applet dhclient<br />
https://aur.archlinux.org/packages/networkmanager-dmenu-git/<br />
# systemctl enable NetworkManager<br />
<br />
make sure there is a polkit agent installed as well:<br />
https://wiki.archlinux.org/index.php/Polkit#Authentication_agents<br />
# pacman -S polkit-gnome<br />
and we need gnome-keyring<br />
# pacman -S gnome-keyring<br />
add<br />
<br />
/usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1 &<br />
<br />
to .xinitrc / .xprofile / i3 config or other<br />
<br />
for dmenu NetworkManager config:<br />
To customize dmenu, copy /usr/share/doc/networkmanager-dmenu-git/config.ini.example into ~/.config/networkmanager-dmenu/config.ini and edit:<br />
<br />
<br />
Desktop Entries<br />
consider installing dex and then adding "dex -a" for autostarting autostart desktop entries... 'dex -ad' will show dry run of which entries those are and you can instead run them manually.<br />
<br />
<br />
Libnotify<br />
<br />
Install a notification server. Probably one of dunst, statnot, twmn<br />
<br />
VPNs<br />
<br />
Status bar<br />
<br />
Shortcuts<br />
<br />
Fonts<br />
<br />
Colors<br />
<br />
Alerts<br />
<br />
Launching<br />
<br />
Appearance<br />
<br />
GTK theme, fonts<br />
<br />
Printing<br />
<br />
zero config networking<br />
<br />
firewall<br />
<br />
screen lock<br />
<br />
i3lock (custom colors version with blur)<br />
https://aur.archlinux.org/packages/xss-lock-git/ to activate lock automatically on suspend/dpms<br />
same author has https://bitbucket.org/raymonad/xss-inhibit/overview<br />
<br />
what gdm gives you<br />
<br />
session mgmt<br />
<br />
polkit<br />
<br />
infinality<br />
yes to this and using infinality repos<br />
<br />
screensaver, screen locking<br />
either<br />
sxlock<br />
i3lock-fancy<br />
xss-lock (maybe with one of the above)<br />
cf https://wiki.archlinux.org/index.php/List_of_applications/Security#Screen_lockers</div>Altercationhttps://wiki.archlinux.org/index.php?title=User:Altercation/Bullet_Proof_i3_Install&diff=462028User:Altercation/Bullet Proof i3 Install2017-01-09T05:19:59Z<p>Altercation: </p>
<hr />
<div>Getting i3 up and running is just the beginning. Unlike a more "heavyweight" and complete desktop environment like Gnome (which I like), tiling window managers are missing a lot of what makes using a computer "seamless". For example, disks probably won't mount automatically, wifi won't come up on its own, etc. Power users will each have their own preferences about what should be done automatically. Sometimes I prefer wifi not scanning every network out there. I may leave that off, but may choose to automount drives I connect to the system. Making these choices means building up your own desktop environment, with a tiling window manager (and linux) at the core.<br />
<br />
display manager or xinitrc<br />
(sddm or nothing at all, though if nothing I need to see what I'm missing)<br />
<br />
using .xprofile or /etc/xprofile<br />
<br />
Power<br />
https://aur.archlinux.org/packages/aclidswitch-git/<br />
tlp, etc.<br />
<br />
xmodmap<br />
<br />
https://wiki.archlinux.org/index.php/Lemonbar<br />
<br />
dmenu<br />
http://dmwit.com/yeganesh/<br />
https://github.com/vicfryzel/xmonad-config<br />
<br />
rofi<br />
<br />
unclutter (there is a rewrite of unclutter in aur that i'm using)<br />
<br />
Networking & Wifi:<br />
sudo pacman -S networkmanager network-manager-applet dhclient<br />
https://aur.archlinux.org/packages/networkmanager-dmenu-git/<br />
# systemctl enable NetworkManager<br />
<br />
make sure there is a polkit agent installed as well:<br />
https://wiki.archlinux.org/index.php/Polkit#Authentication_agents<br />
# pacman -S polkit-gnome<br />
and we need gnome-keyring<br />
# pacman -S gnome-keyring<br />
add<br />
<br />
/usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1 &<br />
<br />
to .xinitrc / .xprofile / i3 config or other<br />
<br />
for dmenu NetworkManager config:<br />
To customize dmenu, copy /usr/share/doc/networkmanager-dmenu-git/config.ini.example into ~/.config/networkmanager-dmenu/config.ini and edit:<br />
<br />
<br />
Desktop Entries<br />
consider installing dex and then adding "dex -a" for autostarting autostart desktop entries... 'dex -ad' will show dry run of which entries those are and you can instead run them manually.<br />
<br />
<br />
Libnotify<br />
<br />
Install a notification server. Probably one of dunst, statnot, twmn<br />
<br />
VPNs<br />
<br />
Status bar<br />
<br />
Shortcuts<br />
<br />
Fonts<br />
<br />
Colors<br />
<br />
Alerts<br />
<br />
Launching<br />
<br />
Appearance<br />
<br />
GTK theme, fonts<br />
<br />
Printing<br />
<br />
zero config networking<br />
<br />
firewall<br />
<br />
screen lock<br />
<br />
i3lock (custom colors version with blur)<br />
https://aur.archlinux.org/packages/xss-lock-git/ to activate lock automatically on suspend/dpms<br />
same author has https://bitbucket.org/raymonad/xss-inhibit/overview<br />
<br />
what gdm gives you<br />
<br />
session mgmt<br />
<br />
polkit<br />
<br />
infinality<br />
yes to this and using infinality repos<br />
<br />
screensaver, screen locking<br />
either<br />
sxlock<br />
i3lock-fancy<br />
xss-lock (maybe with one of the above)</div>Altercationhttps://wiki.archlinux.org/index.php?title=User:Altercation/Bullet_Proof_P50_Notes&diff=461424User:Altercation/Bullet Proof P50 Notes2017-01-04T16:46:49Z<p>Altercation: /* BIOS Configuration */</p>
<hr />
<div><br />
== BIOS Configuration ==<br />
<br />
Currently running with discrete graphics only. Made configuration easier and didn't have to deal with switching between intel/nvidia, but also uses more power.<br />
<br />
Using SecureBoot and sbupdate script to make a secure bootable EFI image.<br />
<br />
<br />
Install TLP and didn't change values to see how it impacts performance<br />
<br />
for bios update I downloaded the cd image from lenovo for the current bios, ran the geteltorito.pl script to convert from .iso to .img, and wrote it to USB drive.<br />
<br />
<br />
There is an update for HDMI related firmware that should fix HDMI output<br />
<br />
KMS required for nvidia driver in order for udev to detect hotplug events</div>Altercationhttps://wiki.archlinux.org/index.php?title=User:Altercation/Bullet_Proof_i3_Install&diff=459489User:Altercation/Bullet Proof i3 Install2016-12-17T06:51:58Z<p>Altercation: </p>
<hr />
<div>Getting i3 up and running is just the beginning. Unlike a more "heavyweight" and complete desktop environment like Gnome (which I like), tiling window managers are missing a lot of what makes using a computer "seamless". For example, disks probably won't mount automatically, wifi won't come up on its own, etc. Power users will each have their own preferences about what should be done automatically. Sometimes I prefer wifi not scanning every network out there. I may leave that off, but may choose to automount drives I connect to the system. Making these choices means building up your own desktop environment, with a tiling window manager (and linux) at the core.<br />
<br />
display manager or xinitrc<br />
<br />
using .xprofile or /etc/xprofile<br />
<br />
Power<br />
https://aur.archlinux.org/packages/aclidswitch-git/<br />
<br />
xmodmap<br />
<br />
https://wiki.archlinux.org/index.php/Lemonbar<br />
<br />
dmenu<br />
http://dmwit.com/yeganesh/<br />
https://github.com/vicfryzel/xmonad-config<br />
<br />
rofi<br />
<br />
unclutter<br />
<br />
Networking & Wifi:<br />
sudo pacman -S networkmanager network-manager-applet dhclient<br />
https://aur.archlinux.org/packages/networkmanager-dmenu-git/<br />
# systemctl enable NetworkManager<br />
<br />
make sure there is a polkit agent installed as well:<br />
https://wiki.archlinux.org/index.php/Polkit#Authentication_agents<br />
# pacman -S polkit-gnome<br />
and we need gnome-keyring<br />
# pacman -S gnome-keyring<br />
add<br />
<br />
/usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1 &<br />
<br />
to .xinitrc / .xprofile / i3 config or other<br />
<br />
for dmenu NetworkManager config:<br />
To customize dmenu, copy /usr/share/doc/networkmanager-dmenu-git/config.ini.example into ~/.config/networkmanager-dmenu/config.ini and edit:<br />
<br />
<br />
Desktop Entries<br />
consider installing dex and then adding "dex -a" for autostarting autostart desktop entries... 'dex -ad' will show dry run of which entries those are and you can instead run them manually.<br />
<br />
<br />
Libnotify<br />
<br />
Install a notification server. Probably one of dunst, statnot, twmn<br />
<br />
VPNs<br />
<br />
Status bar<br />
<br />
Shortcuts<br />
<br />
Fonts<br />
<br />
Colors<br />
<br />
Alerts<br />
<br />
Launching<br />
<br />
Appearance<br />
<br />
GTK theme, fonts<br />
<br />
Printing<br />
<br />
zero config networking<br />
<br />
firewall<br />
<br />
screen lock<br />
<br />
i3lock (custom colors version with blur)<br />
https://aur.archlinux.org/packages/xss-lock-git/ to activate lock automatically on suspend/dpms<br />
same author has https://bitbucket.org/raymonad/xss-inhibit/overview<br />
<br />
what gdm gives you<br />
<br />
session mgmt<br />
<br />
polkit<br />
<br />
infinality</div>Altercationhttps://wiki.archlinux.org/index.php?title=User:Altercation/Bullet_Proof_i3_Install&diff=459488User:Altercation/Bullet Proof i3 Install2016-12-17T06:51:46Z<p>Altercation: </p>
<hr />
<div>Getting i3 up and running is just the beginning. Unlike a more "heavyweight" and complete desktop environment like Gnome (which I like), tiling window managers are missing a lot of what makes using a computer "seamless". For example, disks probably won't mount automatically, wifi won't come up on its own, etc. Power users will each have their own preferences about what should be done automatically. Sometimes I prefer wifi not scanning every network out there. I may leave that off, but may choose to automount drives I connect to the system. Making these choices means building up your own desktop environment, with a tiling window manager (and linux) at the core.<br />
<br />
fonts<br />
<br />
display manager or xinitrc<br />
<br />
using .xprofile or /etc/xprofile<br />
<br />
Power<br />
https://aur.archlinux.org/packages/aclidswitch-git/<br />
<br />
xmodmap<br />
<br />
https://wiki.archlinux.org/index.php/Lemonbar<br />
<br />
dmenu<br />
http://dmwit.com/yeganesh/<br />
https://github.com/vicfryzel/xmonad-config<br />
<br />
rofi<br />
<br />
unclutter<br />
<br />
Networking & Wifi:<br />
sudo pacman -S networkmanager network-manager-applet dhclient<br />
https://aur.archlinux.org/packages/networkmanager-dmenu-git/<br />
# systemctl enable NetworkManager<br />
<br />
make sure there is a polkit agent installed as well:<br />
https://wiki.archlinux.org/index.php/Polkit#Authentication_agents<br />
# pacman -S polkit-gnome<br />
and we need gnome-keyring<br />
# pacman -S gnome-keyring<br />
add<br />
<br />
/usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1 &<br />
<br />
to .xinitrc / .xprofile / i3 config or other<br />
<br />
for dmenu NetworkManager config:<br />
To customize dmenu, copy /usr/share/doc/networkmanager-dmenu-git/config.ini.example into ~/.config/networkmanager-dmenu/config.ini and edit:<br />
<br />
<br />
Desktop Entries<br />
consider installing dex and then adding "dex -a" for autostarting autostart desktop entries... 'dex -ad' will show dry run of which entries those are and you can instead run them manually.<br />
<br />
<br />
Libnotify<br />
<br />
Install a notification server. Probably one of dunst, statnot, twmn<br />
<br />
VPNs<br />
<br />
Status bar<br />
<br />
Shortcuts<br />
<br />
Fonts<br />
<br />
Colors<br />
<br />
Alerts<br />
<br />
Launching<br />
<br />
Appearance<br />
<br />
GTK theme, fonts<br />
<br />
Printing<br />
<br />
zero config networking<br />
<br />
firewall<br />
<br />
screen lock<br />
<br />
i3lock (custom colors version with blur)<br />
https://aur.archlinux.org/packages/xss-lock-git/ to activate lock automatically on suspend/dpms<br />
same author has https://bitbucket.org/raymonad/xss-inhibit/overview<br />
<br />
what gdm gives you<br />
<br />
session mgmt<br />
<br />
polkit<br />
<br />
infinality</div>Altercationhttps://wiki.archlinux.org/index.php?title=User:Altercation/Bullet_Proof_i3_Install&diff=459482User:Altercation/Bullet Proof i3 Install2016-12-17T01:21:15Z<p>Altercation: </p>
<hr />
<div>Getting i3 up and running is just the beginning. Unlike a more "heavyweight" and complete desktop environment like Gnome (which I like), tiling window managers are missing a lot of what makes using a computer "seamless". For example, disks probably won't mount automatically, wifi won't come up on its own, etc. Power users will each have their own preferences about what should be done automatically. Sometimes I prefer wifi not scanning every network out there. I may leave that off, but may choose to automount drives I connect to the system. Making these choices means building up your own desktop environment, with a tiling window manager (and linux) at the core.<br />
<br />
<br />
display manager or xinitrc<br />
<br />
using .xprofile or /etc/xprofile<br />
<br />
Power<br />
https://aur.archlinux.org/packages/aclidswitch-git/<br />
<br />
xmodmap<br />
<br />
https://wiki.archlinux.org/index.php/Lemonbar<br />
<br />
dmenu<br />
http://dmwit.com/yeganesh/<br />
https://github.com/vicfryzel/xmonad-config<br />
<br />
rofi<br />
<br />
unclutter<br />
<br />
Networking & Wifi:<br />
sudo pacman -S networkmanager network-manager-applet dhclient<br />
https://aur.archlinux.org/packages/networkmanager-dmenu-git/<br />
# systemctl enable NetworkManager<br />
<br />
make sure there is a polkit agent installed as well:<br />
https://wiki.archlinux.org/index.php/Polkit#Authentication_agents<br />
# pacman -S polkit-gnome<br />
and we need gnome-keyring<br />
# pacman -S gnome-keyring<br />
add<br />
<br />
/usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1 &<br />
<br />
to .xinitrc / .xprofile / i3 config or other<br />
<br />
for dmenu NetworkManager config:<br />
To customize dmenu, copy /usr/share/doc/networkmanager-dmenu-git/config.ini.example into ~/.config/networkmanager-dmenu/config.ini and edit:<br />
<br />
<br />
Desktop Entries<br />
consider installing dex and then adding "dex -a" for autostarting autostart desktop entries... 'dex -ad' will show dry run of which entries those are and you can instead run them manually.<br />
<br />
<br />
Libnotify<br />
<br />
Install a notification server. Probably one of dunst, statnot, twmn<br />
<br />
VPNs<br />
<br />
Status bar<br />
<br />
Shortcuts<br />
<br />
Fonts<br />
<br />
Colors<br />
<br />
Alerts<br />
<br />
Launching<br />
<br />
Appearance<br />
<br />
GTK theme, fonts<br />
<br />
Printing<br />
<br />
zero config networking<br />
<br />
firewall<br />
<br />
screen lock<br />
<br />
i3lock (custom colors version with blur)<br />
https://aur.archlinux.org/packages/xss-lock-git/ to activate lock automatically on suspend/dpms<br />
same author has https://bitbucket.org/raymonad/xss-inhibit/overview<br />
<br />
what gdm gives you<br />
<br />
session mgmt<br />
<br />
polkit<br />
<br />
infinality</div>Altercationhttps://wiki.archlinux.org/index.php?title=User:Altercation/Bullet_Proof_i3_Install&diff=459481User:Altercation/Bullet Proof i3 Install2016-12-17T01:18:32Z<p>Altercation: </p>
<hr />
<div>Getting i3 up and running is just the beginning. Unlike a more "heavyweight" and complete desktop environment like Gnome (which I like), tiling window managers are missing a lot of what makes using a computer "seamless". For example, disks probably won't mount automatically, wifi won't come up on its own, etc. Power users will each have their own preferences about what should be done automatically. Sometimes I prefer wifi not scanning every network out there. I may leave that off, but may choose to automount drives I connect to the system. Making these choices means building up your own desktop environment, with a tiling window manager (and linux) at the core.<br />
<br />
<br />
display manager or xinitrc<br />
<br />
using .xprofile or /etc/xprofile<br />
<br />
Power<br />
https://aur.archlinux.org/packages/aclidswitch-git/<br />
<br />
xmodmap<br />
<br />
dmenu<br />
http://dmwit.com/yeganesh/<br />
https://github.com/vicfryzel/xmonad-config<br />
<br />
rofi<br />
<br />
unclutter<br />
<br />
Networking & Wifi:<br />
sudo pacman -S networkmanager network-manager-applet dhclient<br />
https://aur.archlinux.org/packages/networkmanager-dmenu-git/<br />
# systemctl enable NetworkManager<br />
<br />
make sure there is a polkit agent installed as well:<br />
https://wiki.archlinux.org/index.php/Polkit#Authentication_agents<br />
# pacman -S polkit-gnome<br />
and we need gnome-keyring<br />
# pacman -S gnome-keyring<br />
add<br />
<br />
/usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1 &<br />
<br />
to .xinitrc / .xprofile / i3 config or other<br />
<br />
for dmenu NetworkManager config:<br />
To customize dmenu, copy /usr/share/doc/networkmanager-dmenu-git/config.ini.example into ~/.config/networkmanager-dmenu/config.ini and edit:<br />
<br />
<br />
Desktop Entries<br />
consider installing dex and then adding "dex -a" for autostarting autostart desktop entries... 'dex -ad' will show dry run of which entries those are and you can instead run them manually.<br />
<br />
<br />
Libnotify<br />
<br />
Install a notification server. Probably one of dunst, statnot, twmn<br />
<br />
VPNs<br />
<br />
Status bar<br />
<br />
Shortcuts<br />
<br />
Fonts<br />
<br />
Colors<br />
<br />
Alerts<br />
<br />
Launching<br />
<br />
Appearance<br />
<br />
GTK theme, fonts<br />
<br />
Printing<br />
<br />
zero config networking<br />
<br />
firewall<br />
<br />
screen lock<br />
<br />
i3lock (custom colors version with blur)<br />
https://aur.archlinux.org/packages/xss-lock-git/ to activate lock automatically on suspend/dpms<br />
same author has https://bitbucket.org/raymonad/xss-inhibit/overview<br />
<br />
what gdm gives you<br />
<br />
session mgmt<br />
<br />
polkit<br />
<br />
infinality</div>Altercationhttps://wiki.archlinux.org/index.php?title=User:Altercation/Bullet_Proof_i3_Install&diff=459359User:Altercation/Bullet Proof i3 Install2016-12-15T03:18:22Z<p>Altercation: </p>
<hr />
<div>Getting i3 up and running is just the beginning. Unlike a more "heavyweight" and complete desktop environment like Gnome (which I like), tiling window managers are missing a lot of what makes using a computer "seamless". For example, disks probably won't mount automatically, wifi won't come up on its own, etc. Power users will each have their own preferences about what should be done automatically. Sometimes I prefer wifi not scanning every network out there. I may leave that off, but may choose to automount drives I connect to the system. Making these choices means building up your own desktop environment, with a tiling window manager (and linux) at the core.<br />
<br />
<br />
display manager or xinitrc<br />
<br />
using .xprofile or /etc/xprofile<br />
<br />
Power<br />
https://aur.archlinux.org/packages/aclidswitch-git/<br />
<br />
xmodmap<br />
<br />
dmenu<br />
<br />
rofi<br />
<br />
unclutter<br />
<br />
Networking & Wifi:<br />
sudo pacman -S networkmanager network-manager-applet dhclient<br />
https://aur.archlinux.org/packages/networkmanager-dmenu-git/<br />
# systemctl enable NetworkManager<br />
<br />
make sure there is a polkit agent installed as well:<br />
https://wiki.archlinux.org/index.php/Polkit#Authentication_agents<br />
# pacman -S polkit-gnome<br />
and we need gnome-keyring<br />
# pacman -S gnome-keyring<br />
add<br />
<br />
/usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1 &<br />
<br />
to .xinitrc / .xprofile / i3 config or other<br />
<br />
for dmenu NetworkManager config:<br />
To customize dmenu, copy /usr/share/doc/networkmanager-dmenu-git/config.ini.example into ~/.config/networkmanager-dmenu/config.ini and edit:<br />
<br />
<br />
Desktop Entries<br />
consider installing dex and then adding "dex -a" for autostarting autostart desktop entries... 'dex -ad' will show dry run of which entries those are and you can instead run them manually.<br />
<br />
<br />
Libnotify<br />
<br />
Install a notification server. Probably one of dunst, statnot, twmn<br />
<br />
VPNs<br />
<br />
Status bar<br />
<br />
Shortcuts<br />
<br />
Fonts<br />
<br />
Colors<br />
<br />
Alerts<br />
<br />
Launching<br />
<br />
Appearance<br />
<br />
GTK theme, fonts<br />
<br />
Printing<br />
<br />
zero config networking<br />
<br />
firewall<br />
<br />
screen lock<br />
<br />
i3lock (custom colors version with blur)<br />
https://aur.archlinux.org/packages/xss-lock-git/ to activate lock automatically on suspend/dpms<br />
same author has https://bitbucket.org/raymonad/xss-inhibit/overview<br />
<br />
what gdm gives you<br />
<br />
session mgmt<br />
<br />
polkit<br />
<br />
infinality</div>Altercationhttps://wiki.archlinux.org/index.php?title=User:Altercation/Bullet_Proof_i3_Install&diff=459358User:Altercation/Bullet Proof i3 Install2016-12-15T03:14:40Z<p>Altercation: </p>
<hr />
<div>Getting i3 up and running is just the beginning. Unlike a more "heavyweight" and complete desktop environment like Gnome (which I like), tiling window managers are missing a lot of what makes using a computer "seamless". For example, disks probably won't mount automatically, wifi won't come up on its own, etc. Power users will each have their own preferences about what should be done automatically. Sometimes I prefer wifi not scanning every network out there. I may leave that off, but may choose to automount drives I connect to the system. Making these choices means building up your own desktop environment, with a tiling window manager (and linux) at the core.<br />
<br />
<br />
display manager or xinitrc<br />
<br />
using .xprofile or /etc/xprofile<br />
<br />
Power<br />
https://aur.archlinux.org/packages/aclidswitch-git/<br />
<br />
xmodmap<br />
<br />
dmenu<br />
<br />
rofi<br />
<br />
unclutter<br />
<br />
Networking & Wifi:<br />
sudo pacman -S networkmanager network-manager-applet dhclient<br />
https://aur.archlinux.org/packages/networkmanager-dmenu-git/<br />
# systemctl enable NetworkManager<br />
<br />
make sure there is a polkit agent installed as well:<br />
https://wiki.archlinux.org/index.php/Polkit#Authentication_agents<br />
# pacman -S polkit-gnome<br />
and we need gnome-keyring<br />
# pacman -S gnome-keyring<br />
add<br />
<br />
/usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1 &<br />
<br />
to .xinitrc / .xprofile / i3 config or other<br />
<br />
for dmenu NetworkManager config:<br />
To customize dmenu, copy /usr/share/doc/networkmanager-dmenu-git/config.ini.example into ~/.config/networkmanager-dmenu/config.ini and edit:<br />
<br />
<br />
Desktop Entries<br />
consider installing dex and then adding "dex -a" for autostarting autostart desktop entries... 'dex -ad' will show dry run of which entries those are and you can instead run them manually.<br />
<br />
<br />
Libnotify<br />
<br />
Install a notification server. Probably one of dunst, statnot, twmn<br />
<br />
VPNs<br />
<br />
Status bar<br />
<br />
Shortcuts<br />
<br />
Fonts<br />
<br />
Colors<br />
<br />
Alerts<br />
<br />
Launching<br />
<br />
Appearance<br />
<br />
GTK theme, fonts<br />
<br />
Printing<br />
<br />
zero config networking<br />
<br />
firewall<br />
<br />
screen lock<br />
<br />
i3lock (custom colors version with blur)<br />
https://aur.archlinux.org/packages/xss-lock-git/ to activate lock automatically on suspend/dpms<br />
<br />
what gdm gives you<br />
<br />
session mgmt<br />
<br />
polkit<br />
<br />
infinality</div>Altercationhttps://wiki.archlinux.org/index.php?title=User:Altercation/Bullet_Proof_i3_Install&diff=459357User:Altercation/Bullet Proof i3 Install2016-12-15T03:03:03Z<p>Altercation: </p>
<hr />
<div>Getting i3 up and running is just the beginning. Unlike a more "heavyweight" and complete desktop environment like Gnome (which I like), tiling window managers are missing a lot of what makes using a computer "seamless". For example, disks probably won't mount automatically, wifi won't come up on its own, etc. Power users will each have their own preferences about what should be done automatically. Sometimes I prefer wifi not scanning every network out there. I may leave that off, but may choose to automount drives I connect to the system. Making these choices means building up your own desktop environment, with a tiling window manager (and linux) at the core.<br />
<br />
<br />
display manager or xinitrc<br />
<br />
using .xprofile or /etc/xprofile<br />
<br />
Power<br />
https://aur.archlinux.org/packages/aclidswitch-git/<br />
<br />
xmodmap<br />
<br />
dmenu<br />
<br />
rofi<br />
<br />
unclutter<br />
<br />
Networking & Wifi:<br />
sudo pacman -S networkmanager network-manager-applet dhclient<br />
https://aur.archlinux.org/packages/networkmanager-dmenu-git/<br />
# systemctl enable NetworkManager<br />
<br />
make sure there is a polkit agent installed as well:<br />
https://wiki.archlinux.org/index.php/Polkit#Authentication_agents<br />
# pacman -S polkit-gnome<br />
and we need gnome-keyring<br />
# pacman -S gnome-keyring<br />
add<br />
<br />
/usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1 &<br />
<br />
to .xinitrc / .xprofile / i3 config or other<br />
<br />
for dmenu NetworkManager config:<br />
To customize dmenu, copy /usr/share/doc/networkmanager-dmenu-git/config.ini.example into ~/.config/networkmanager-dmenu/config.ini and edit:<br />
<br />
<br />
Desktop Entries<br />
consider installing dex and then adding "dex -a" for autostarting autostart desktop entries... 'dex -ad' will show dry run of which entries those are and you can instead run them manually.<br />
<br />
<br />
Libnotify<br />
<br />
Install a notification server. Probably one of dunst, statnot, twmn<br />
<br />
VPNs<br />
<br />
Status bar<br />
<br />
Shortcuts<br />
<br />
Fonts<br />
<br />
Colors<br />
<br />
Alerts<br />
<br />
Launching<br />
<br />
Appearance<br />
<br />
GTK theme, fonts<br />
<br />
Printing<br />
<br />
zero config networking<br />
<br />
firewall<br />
<br />
screen lock<br />
<br />
what gdm gives you<br />
<br />
session mgmt<br />
<br />
polkit<br />
<br />
infinality</div>Altercationhttps://wiki.archlinux.org/index.php?title=User:Altercation/Bullet_Proof_i3_Install&diff=459337User:Altercation/Bullet Proof i3 Install2016-12-14T18:48:52Z<p>Altercation: </p>
<hr />
<div>Getting i3 up and running is just the beginning. Unlike a more "heavyweight" and complete desktop environment like Gnome (which I like), tiling window managers are missing a lot of what makes using a computer "seamless". For example, disks probably won't mount automatically, wifi won't come up on its own, etc. Power users will each have their own preferences about what should be done automatically. Sometimes I prefer wifi not scanning every network out there. I may leave that off, but may choose to automount drives I connect to the system. Making these choices means building up your own desktop environment, with a tiling window manager (and linux) at the core.<br />
<br />
<br />
display manager or xinitrc<br />
<br />
using .xprofile or /etc/xprofile<br />
<br />
Power<br />
<br />
xmodmap<br />
<br />
dmenu<br />
<br />
rofi<br />
<br />
unclutter<br />
<br />
Networking & Wifi:<br />
sudo pacman -S networkmanager network-manager-applet dhclient<br />
https://aur.archlinux.org/packages/networkmanager-dmenu-git/<br />
# systemctl enable NetworkManager<br />
<br />
make sure there is a polkit agent installed as well:<br />
https://wiki.archlinux.org/index.php/Polkit#Authentication_agents<br />
# pacman -S polkit-gnome<br />
and we need gnome-keyring<br />
# pacman -S gnome-keyring<br />
add<br />
<br />
/usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1 &<br />
<br />
to .xinitrc / .xprofile / i3 config or other<br />
<br />
for dmenu NetworkManager config:<br />
To customize dmenu, copy /usr/share/doc/networkmanager-dmenu-git/config.ini.example into ~/.config/networkmanager-dmenu/config.ini and edit:<br />
<br />
<br />
Desktop Entries<br />
consider installing dex and then adding "dex -a" for autostarting autostart desktop entries... 'dex -ad' will show dry run of which entries those are and you can instead run them manually.<br />
<br />
<br />
Libnotify<br />
<br />
Install a notification server. Probably one of dunst, statnot, twmn<br />
<br />
VPNs<br />
<br />
Status bar<br />
<br />
Shortcuts<br />
<br />
Fonts<br />
<br />
Colors<br />
<br />
Alerts<br />
<br />
Launching<br />
<br />
Appearance<br />
<br />
GTK theme, fonts<br />
<br />
Printing<br />
<br />
zero config networking<br />
<br />
firewall<br />
<br />
screen lock<br />
<br />
what gdm gives you<br />
<br />
session mgmt<br />
<br />
polkit<br />
<br />
infinality</div>Altercationhttps://wiki.archlinux.org/index.php?title=User:Altercation/Bullet_Proof_i3_Install&diff=459336User:Altercation/Bullet Proof i3 Install2016-12-14T18:44:01Z<p>Altercation: </p>
<hr />
<div>Getting i3 up and running is just the beginning. Unlike a more "heavyweight" and complete desktop environment like Gnome (which I like), tiling window managers are missing a lot of what makes using a computer "seamless". For example, disks probably won't mount automatically, wifi won't come up on its own, etc. Power users will each have their own preferences about what should be done automatically. Sometimes I prefer wifi not scanning every network out there. I may leave that off, but may choose to automount drives I connect to the system. Making these choices means building up your own desktop environment, with a tiling window manager (and linux) at the core.<br />
<br />
<br />
display manager or xinitrc<br />
<br />
using .xprofile or /etc/xprofile<br />
<br />
Power<br />
<br />
xmodmap<br />
<br />
dmenu<br />
<br />
rofi<br />
<br />
unclutter<br />
<br />
Networking & Wifi:<br />
sudo pacman -S networkmanager network-manager-applet dhclient<br />
https://aur.archlinux.org/packages/networkmanager-dmenu-git/<br />
# systemctl enable NetworkManager<br />
<br />
make sure there is a polkit agent installed as well:<br />
https://wiki.archlinux.org/index.php/Polkit#Authentication_agents<br />
# pacman -S polkit-gnome<br />
and we need gnome-keyring<br />
# pacman -S gnome-keyring<br />
add<br />
<br />
/usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1 &<br />
<br />
to .xinitrc / .xprofile / i3 config or other<br />
<br />
for dmenu NetworkManager config:<br />
To customize dmenu, copy /usr/share/doc/networkmanager-dmenu-git/config.ini.example into ~/.config/networkmanager-dmenu/config.ini and edit:<br />
<br />
<br />
Desktop Entries<br />
consider installing dex and then adding "dex -a" for autostarting autostart desktop entries... 'dex -ad' will show dry run of which entries those are and you can instead run them manually.<br />
<br />
<br />
VPNs<br />
<br />
Status bar<br />
<br />
Shortcuts<br />
<br />
Fonts<br />
<br />
Colors<br />
<br />
Alerts<br />
<br />
Launching<br />
<br />
Appearance<br />
<br />
GTK theme, fonts<br />
<br />
Printing<br />
<br />
zero config networking<br />
<br />
firewall<br />
<br />
screen lock<br />
<br />
what gdm gives you<br />
<br />
session mgmt<br />
<br />
polkit<br />
<br />
infinality</div>Altercationhttps://wiki.archlinux.org/index.php?title=User:Altercation/Bullet_Proof_i3_Install&diff=459335User:Altercation/Bullet Proof i3 Install2016-12-14T18:30:12Z<p>Altercation: </p>
<hr />
<div>Getting i3 up and running is just the beginning. Unlike a more "heavyweight" and complete desktop environment like Gnome (which I like), tiling window managers are missing a lot of what makes using a computer "seamless". For example, disks probably won't mount automatically, wifi won't come up on its own, etc. Power users will each have their own preferences about what should be done automatically. Sometimes I prefer wifi not scanning every network out there. I may leave that off, but may choose to automount drives I connect to the system. Making these choices means building up your own desktop environment, with a tiling window manager (and linux) at the core.<br />
<br />
<br />
display manager or xinitrc<br />
<br />
using .xprofile or /etc/xprofile<br />
<br />
Power<br />
<br />
xmodmap<br />
<br />
dmenu<br />
<br />
rofi<br />
<br />
unclutter<br />
<br />
Networking & Wifi:<br />
sudo pacman -S networkmanager network-manager-applet dhclient<br />
https://aur.archlinux.org/packages/networkmanager-dmenu-git/<br />
# systemctl enable NetworkManager<br />
<br />
make sure there is a polkit agent installed as well:<br />
https://wiki.archlinux.org/index.php/Polkit#Authentication_agents<br />
# pacman -S polkit-gnome<br />
and we need gnome-keyring<br />
# pacman -S gnome-keyring<br />
add<br />
<br />
/usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1 &<br />
<br />
to .xinitrc / .xprofile / i3 config or other<br />
<br />
Desktop Entries<br />
consider installing dex and then adding "dex -a" for autostarting autostart desktop entries... 'dex -ad' will show dry run of which entries those are and you can instead run them manually.<br />
<br />
<br />
VPNs<br />
<br />
Status bar<br />
<br />
Shortcuts<br />
<br />
Fonts<br />
<br />
Colors<br />
<br />
Alerts<br />
<br />
Launching<br />
<br />
Appearance<br />
<br />
GTK theme, fonts<br />
<br />
Printing<br />
<br />
zero config networking<br />
<br />
firewall<br />
<br />
screen lock<br />
<br />
what gdm gives you<br />
<br />
session mgmt<br />
<br />
polkit<br />
<br />
infinality</div>Altercationhttps://wiki.archlinux.org/index.php?title=User:Altercation/Bullet_Proof_i3_Install&diff=459331User:Altercation/Bullet Proof i3 Install2016-12-14T18:16:22Z<p>Altercation: </p>
<hr />
<div>Getting i3 up and running is just the beginning. Unlike a more "heavyweight" and complete desktop environment like Gnome (which I like), tiling window managers are missing a lot of what makes using a computer "seamless". For example, disks probably won't mount automatically, wifi won't come up on its own, etc. Power users will each have their own preferences about what should be done automatically. Sometimes I prefer wifi not scanning every network out there. I may leave that off, but may choose to automount drives I connect to the system. Making these choices means building up your own desktop environment, with a tiling window manager (and linux) at the core.<br />
<br />
<br />
display manager or xinitrc<br />
<br />
using .xprofile or /etc/xprofile<br />
<br />
Power<br />
<br />
xmodmap<br />
<br />
dmenu<br />
<br />
rofi<br />
<br />
unclutter<br />
<br />
Networking & Wifi:<br />
sudo pacman -S networkmanager network-manager-applet dhclient<br />
https://aur.archlinux.org/packages/networkmanager-dmenu-git/<br />
# systemctl enable NetworkManager<br />
<br />
make sure there is a polkit agent installed as well:<br />
https://wiki.archlinux.org/index.php/Polkit#Authentication_agents<br />
add<br />
<br />
/usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1 &<br />
<br />
to .xinitrc / .xprofile / i3 config or other<br />
<br />
Desktop Entries<br />
consider installing dex and then adding "dex -a" for autostarting autostart desktop entries... 'dex -ad' will show dry run of which entries those are and you can instead run them manually.<br />
<br />
<br />
VPNs<br />
<br />
Status bar<br />
<br />
Shortcuts<br />
<br />
Fonts<br />
<br />
Colors<br />
<br />
Alerts<br />
<br />
Launching<br />
<br />
Appearance<br />
<br />
GTK theme, fonts<br />
<br />
Printing<br />
<br />
zero config networking<br />
<br />
firewall<br />
<br />
screen lock<br />
<br />
what gdm gives you<br />
<br />
session mgmt<br />
<br />
polkit<br />
<br />
infinality</div>Altercationhttps://wiki.archlinux.org/index.php?title=User:Altercation/Bullet_Proof_i3_Install&diff=459330User:Altercation/Bullet Proof i3 Install2016-12-14T18:11:14Z<p>Altercation: </p>
<hr />
<div>Getting i3 up and running is just the beginning. Unlike a more "heavyweight" and complete desktop environment like Gnome (which I like), tiling window managers are missing a lot of what makes using a computer "seamless". For example, disks probably won't mount automatically, wifi won't come up on its own, etc. Power users will each have their own preferences about what should be done automatically. Sometimes I prefer wifi not scanning every network out there. I may leave that off, but may choose to automount drives I connect to the system. Making these choices means building up your own desktop environment, with a tiling window manager (and linux) at the core.<br />
<br />
<br />
display manager or xinitrc<br />
<br />
using .xprofile or /etc/xprofile<br />
<br />
Power<br />
<br />
xmodmap<br />
<br />
dmenu<br />
<br />
rofi<br />
<br />
unclutter<br />
<br />
Networking & Wifi:<br />
sudo pacman -S networkmanager network-manager-applet dhclient<br />
https://aur.archlinux.org/packages/networkmanager-dmenu-git/<br />
# systemctl enable NetworkManager<br />
<br />
make sure there is a polkit agent installed as well:<br />
https://wiki.archlinux.org/index.php/Polkit#Authentication_agents<br />
<br />
<br />
VPNs<br />
<br />
Status bar<br />
<br />
Shortcuts<br />
<br />
Fonts<br />
<br />
Colors<br />
<br />
Alerts<br />
<br />
Launching<br />
<br />
Appearance<br />
<br />
GTK theme, fonts<br />
<br />
Printing<br />
<br />
zero config networking<br />
<br />
firewall<br />
<br />
screen lock<br />
<br />
what gdm gives you<br />
<br />
session mgmt<br />
<br />
polkit<br />
<br />
infinality</div>Altercationhttps://wiki.archlinux.org/index.php?title=User:Altercation/Bullet_Proof_i3_Install&diff=459328User:Altercation/Bullet Proof i3 Install2016-12-14T18:09:25Z<p>Altercation: </p>
<hr />
<div>Getting i3 up and running is just the beginning. Unlike a more "heavyweight" and complete desktop environment like Gnome (which I like), tiling window managers are missing a lot of what makes using a computer "seamless". For example, disks probably won't mount automatically, wifi won't come up on its own, etc. Power users will each have their own preferences about what should be done automatically. Sometimes I prefer wifi not scanning every network out there. I may leave that off, but may choose to automount drives I connect to the system. Making these choices means building up your own desktop environment, with a tiling window manager (and linux) at the core.<br />
<br />
<br />
display manager or xinitrc<br />
<br />
using .xprofile or /etc/xprofile<br />
<br />
Power<br />
<br />
xmodmap<br />
<br />
dmenu<br />
<br />
rofi<br />
<br />
unclutter<br />
<br />
Networking & Wifi:<br />
sudo pacman -S networkmanager network-manager-applet dhclient<br />
https://aur.archlinux.org/packages/networkmanager-dmenu-git/<br />
# systemctl enable NetworkManager<br />
<br />
<br />
VPNs<br />
<br />
Status bar<br />
<br />
Shortcuts<br />
<br />
Fonts<br />
<br />
Colors<br />
<br />
Alerts<br />
<br />
Launching<br />
<br />
Appearance<br />
<br />
GTK theme, fonts<br />
<br />
Printing<br />
<br />
zero config networking<br />
<br />
firewall<br />
<br />
screen lock<br />
<br />
what gdm gives you<br />
<br />
session mgmt<br />
<br />
polkit<br />
<br />
infinality</div>Altercationhttps://wiki.archlinux.org/index.php?title=User:Altercation/Bullet_Proof_i3_Install&diff=459326User:Altercation/Bullet Proof i3 Install2016-12-14T18:06:57Z<p>Altercation: </p>
<hr />
<div>Getting i3 up and running is just the beginning. Unlike a more "heavyweight" and complete desktop environment like Gnome (which I like), tiling window managers are missing a lot of what makes using a computer "seamless". For example, disks probably won't mount automatically, wifi won't come up on its own, etc. Power users will each have their own preferences about what should be done automatically. Sometimes I prefer wifi not scanning every network out there. I may leave that off, but may choose to automount drives I connect to the system. Making these choices means building up your own desktop environment, with a tiling window manager (and linux) at the core.<br />
<br />
<br />
display manager or xinitrc<br />
<br />
using .xprofile or /etc/xprofile<br />
<br />
Power<br />
<br />
xmodmap<br />
<br />
dmenu<br />
<br />
rofi<br />
<br />
unclutter<br />
<br />
Networking & Wifi:<br />
sudo pacman -S networkmanager network-manager-applet dhclient<br />
https://aur.archlinux.org/packages/networkmanager-dmenu-git/<br />
<br />
<br />
VPNs<br />
<br />
Status bar<br />
<br />
Shortcuts<br />
<br />
Fonts<br />
<br />
Colors<br />
<br />
Alerts<br />
<br />
Launching<br />
<br />
Appearance<br />
<br />
GTK theme, fonts<br />
<br />
Printing<br />
<br />
zero config networking<br />
<br />
firewall<br />
<br />
screen lock<br />
<br />
what gdm gives you<br />
<br />
session mgmt<br />
<br />
polkit<br />
<br />
infinality</div>Altercationhttps://wiki.archlinux.org/index.php?title=User:Altercation/Bullet_Proof_i3_Install&diff=459236User:Altercation/Bullet Proof i3 Install2016-12-13T21:39:13Z<p>Altercation: </p>
<hr />
<div>Getting i3 up and running is just the beginning. Unlike a more "heavyweight" and complete desktop environment like Gnome (which I like), tiling window managers are missing a lot of what makes using a computer "seamless". For example, disks probably won't mount automatically, wifi won't come up on its own, etc. Power users will each have their own preferences about what should be done automatically. Sometimes I prefer wifi not scanning every network out there. I may leave that off, but may choose to automount drives I connect to the system. Making these choices means building up your own desktop environment, with a tiling window manager (and linux) at the core.<br />
<br />
<br />
display manager or xinitrc<br />
<br />
using .xprofile or /etc/xprofile<br />
<br />
Power<br />
<br />
xmodmap<br />
<br />
dmenu<br />
<br />
rofi<br />
<br />
unclutter<br />
<br />
Networking & Wifi<br />
<br />
VPNs<br />
<br />
Status bar<br />
<br />
Shortcuts<br />
<br />
Fonts<br />
<br />
Colors<br />
<br />
Alerts<br />
<br />
Launching<br />
<br />
Appearance<br />
<br />
GTK theme, fonts<br />
<br />
Printing<br />
<br />
zero config networking<br />
<br />
firewall<br />
<br />
screen lock<br />
<br />
what gdm gives you<br />
<br />
session mgmt<br />
<br />
polkit<br />
<br />
infinality</div>Altercationhttps://wiki.archlinux.org/index.php?title=User:Altercation/Bullet_Proof_i3_Install&diff=459235User:Altercation/Bullet Proof i3 Install2016-12-13T21:21:35Z<p>Altercation: </p>
<hr />
<div>Getting i3 up and running is just the beginning. Unlike a more "heavyweight" and complete desktop environment like Gnome (which I like), tiling window managers are missing a lot of what makes using a computer "seamless". For example, disks probably won't mount automatically, wifi won't come up on its own, etc. Power users will each have their own preferences about what should be done automatically. Sometimes I prefer wifi not scanning every network out there. I may leave that off, but may choose to automount drives I connect to the system. Making these choices means building up your own desktop environment, with a tiling window manager (and linux) at the core.<br />
<br />
<br />
display manager or xinitrc<br />
<br />
using .xprofile or /etc/xprofile<br />
<br />
Power<br />
<br />
xmodmap<br />
<br />
dmenu<br />
<br />
unclutter<br />
<br />
Networking & Wifi<br />
<br />
VPNs<br />
<br />
Status bar<br />
<br />
Shortcuts<br />
<br />
Fonts<br />
<br />
Colors<br />
<br />
Alerts<br />
<br />
Launching<br />
<br />
Appearance<br />
<br />
GTK theme, fonts<br />
<br />
Printing<br />
<br />
zero config networking<br />
<br />
firewall<br />
<br />
screen lock<br />
<br />
what gdm gives you<br />
<br />
session mgmt<br />
<br />
polkit<br />
<br />
infinality</div>Altercationhttps://wiki.archlinux.org/index.php?title=User:Altercation/Bullet_Proof_P50_Notes&diff=459049User:Altercation/Bullet Proof P50 Notes2016-12-11T17:39:45Z<p>Altercation: </p>
<hr />
<div><br />
== BIOS Configuration ==<br />
<br />
Currently running with discrete graphics only. Made configuration easier and didn't have to deal with switching between intel/nvidia, but also uses more power.<br />
<br />
Using SecureBoot and sbupdate script to make a secure bootable EFI image.<br />
<br />
<br />
Install TLP and didn't change values to see how it impacts performance<br />
<br />
for bios update I downloaded the cd image from lenovo for the current bios, ran the geteltorito.pl script to convert from .iso to .img, and wrote it to USB drive.</div>Altercationhttps://wiki.archlinux.org/index.php?title=User:Altercation/Bullet_Proof_P50_Notes&diff=459047User:Altercation/Bullet Proof P50 Notes2016-12-11T17:30:02Z<p>Altercation: /* BIOS Configuration */</p>
<hr />
<div><br />
== BIOS Configuration ==<br />
<br />
Currently running with discrete graphics only. Made configuration easier and didn't have to deal with switching between intel/nvidia, but also uses more power.<br />
<br />
Using SecureBoot and sbupdate script to make a secure bootable EFI image.<br />
<br />
<br />
Install TLP and didn't change values to see how it impacts performance</div>Altercationhttps://wiki.archlinux.org/index.php?title=User:Altercation/Bullet_Proof_P50_Notes&diff=459046User:Altercation/Bullet Proof P50 Notes2016-12-11T17:29:27Z<p>Altercation: Created page with " == BIOS Configuration == Currently running with discrete graphics only. Made configuration easier and didn't have to deal with switching between intel/nvidia, but also uses..."</p>
<hr />
<div><br />
== BIOS Configuration ==<br />
<br />
Currently running with discrete graphics only. Made configuration easier and didn't have to deal with switching between intel/nvidia, but also uses more power.<br />
<br />
Using SecureBoot and sbupdate script to make a secure bootable EFI image.</div>Altercationhttps://wiki.archlinux.org/index.php?title=User:Altercation/Bullet_Proof_Arch_Recovery&diff=458996User:Altercation/Bullet Proof Arch Recovery2016-12-10T23:22:32Z<p>Altercation: </p>
<hr />
<div><br />
<br />
Scenario: DRIVE GOOD, NEW MACHINE<br />
<br />
A mainboard replacement or moving the main drive to new machine will result in two main issues:<br />
<br />
1. EFI boot entry will be gone<br />
2. Keys will be missing for secure boot<br />
<br />
We will add entries using efibootmgr to both manage keys and boot the system.<br />
<br />
1. Boot arch iso USB drive<br />
2. {ic|lsblk -o +PARTLABEL,LABEL} to identify the system drive and partitions<br />
3. Unlock the cryptsystem partition to a container named system<br />
3. Mount the system container to /mnt<br />
4. "Boot" that partition with "systemd-nspawn -bD /mnt"<br />
5. examine the /etc/commandline entry</div>Altercationhttps://wiki.archlinux.org/index.php?title=User:Altercation/Bullet_Proof_Arch_Recovery&diff=458995User:Altercation/Bullet Proof Arch Recovery2016-12-10T22:33:41Z<p>Altercation: </p>
<hr />
<div><br />
<br />
Scenario: DRIVE GOOD, NEW MACHINE<br />
<br />
A mainboard replacement or moving the main drive to new machine will result in two main issues:<br />
<br />
1. EFI boot entry will be gone<br />
2. Keys will be missing for secure boot<br />
<br />
We will add entries using efibootmgr to both manage keys and boot the system.</div>Altercationhttps://wiki.archlinux.org/index.php?title=User:Altercation/Bullet_Proof_Arch_Recovery&diff=458979User:Altercation/Bullet Proof Arch Recovery2016-12-10T19:35:48Z<p>Altercation: Created page with "Stub"</p>
<hr />
<div>Stub</div>Altercationhttps://wiki.archlinux.org/index.php?title=User:Altercation/Bullet_Proof_Arch_Install&diff=458974User:Altercation/Bullet Proof Arch Install2016-12-10T18:08:56Z<p>Altercation: /* Partition Drive */</p>
<hr />
<div>This page is a summary of the current process I follow when installing Arch on a new laptop or desktop. My process varies over time, but this serves as my "state of the art" best practice recommendations. I'm open to feedback and suggestions for improvements.<br />
<br />
{{Note|This is entirely based on my own opinions and research. It is opinionated about the best way to do things given the current state of the kernel, hardware availability, and utilities, filesystems, etc. I will explain my rationale for specific choices and provide links to other sources of information (on the Arch wiki or external) where useful.}}<br />
<br />
== Objectives ==<br />
<br />
The goals of my standard "bullet proof" Arch Linux installation are:<br />
<br />
* Benefit from Arch's rolling release model while mitigating any risk of system corruption or data loss due to failed upgrades<br />
* Minimize risk due to hardware failure or total system loss (e.g. theft or physical destruction)<br />
* Make system rollbacks easy and procedural, using a standard setup and methodology for recovery of previous system (and user data) states<br />
<br />
=== Why not the Arch Install instructions? ===<br />
<br />
The [[Installation guide|Arch Linux installation instructions]] are an excellent, general starting point and you should read and understand them. That being said, they are designed to map to a very, very broad set of installation scenarios. I am interested in a very specific type of installation (daily use desktops and laptops in this article) and I have a strong set of opinions about the "right" or "best practice" way to set up my own working systems.<br />
<br />
These instructions, then, are much more prescriptive and have strong suggestions or directions about how (and why) one should use a particular method during Arch Linux installation.<br />
<br />
=== Key differences from the stock Arch install instructions ===<br />
<br />
How these instructions differ from the standard Arch guidance:<br />
<br />
* We are encrypting the entire system but not using LVM as is often recommended (see the encryption section below for details about why we are not using it).<br />
* I use labels and avoid UUIDs where possible to make switching to an alternate recovery drive easier.<br />
* I skip arch-chroot and simply boot the new system ('''not''' reboot, just boot) from within the install environment using {{Man|1|systemd-nspawn}} which enables the *ctl commands to work (and systemd services to be enabled properly without need for a system reboot)<br />
* I use the various systemd *ctl commands (hostnamectl, timedatectl, localectl, etc.) to configure the system<br />
* I use the systemd mkinitcpio hooks in lieu of the legacy hooks.<br />
* I use BTRFS exclusively for root and home partitions for its backup capabilities.<br />
* I recommend and use secure boot (but not with the Microsoft keys) to minimize risk due to the unavoidably unencrypted EFI partition.<br />
<br />
== Assumptions ==<br />
<br />
These instructions presuppose the following:<br />
<br />
* fairly new hardware (these instructions may work on older hardware, but there may be unusual issues that crop up... if you aren't comfortable handling those situations you should consider a more "traditional" Arch Linux install (e.g. using grub, LVM, ext4, etc.)<br />
* [[Unified Extensible Firmware Interface|UEFI support]] (BIOS system install is also possible with some modification of these instructions, but this has not yet been detailed here)<br />
* probably an [[Solid State Drives|SSD]].<br />
* some familiarity with Arch, or at least some experience with Linux, will help<br />
<br />
{{Warning|I am assuming you are going to single boot (not dual boot) and that you are '''willing to wipe all data from the install drive.''' If that is not the case, do not proceed with these instructions as following them '''will effectively destroy any data (and other operating systems) on the installation target drive.'''}}<br />
<br />
== Prerequisites ==<br />
<br />
You must have a recent copy of the Arch install USB. See [[:Category:Getting and installing Arch]] for general information and [[USB flash installation media]] for specific details on creating a USB Arch installation drive.<br />
<br />
You should also have a reasonable amount of time in which to complete the installation. Novice users will want to budget a couple hours. Experienced users will ''know'' to budget a couple hours.<br />
<br />
== Preparation ==<br />
<br />
=== Boot from USB Drive ===<br />
<br />
Boot your system from your prepared [[USB flash installation media|Arch Linux USB drive]]. It is important that you boot in EFI mode, not legacy BIOS compatibility mode. See the [[Unified Extensible Firmware Interface|UEFI]] article for more information about checking boot mode and ensuring you are booting using EFI.<br />
<br />
=== Bring up the network ===<br />
<br />
If you booted into a system with an ethernet cable plugged in, chances are you're up and running. If you need to use wireless instead, {{ic|wifi-menu}} will more often than not work without trouble. If those don't work, see [[Installation guide#Connect to the Internet|the Arch installation guide section on connecting to the internet]].<br />
<br />
=== Select Drive ===<br />
<br />
I like to use the [[Core utilities#lsblk|{{ic|1=lsblk}}]] command to bring up a quick list of the block devices on the system and identify existing partition structures and sizes, as well as mount points. If you don't already use it, I recommend [[Core utilities#lsblk|{{ic|1=lsblk}}]] when you need information on any given drive or partition. It's useful for polling UUIDs as well. For example, the following command gives you a clearly formatted summary of all block devices, their partition labels, filesystem lables, UUIDs and partition UUIDS: {{ic|lsblk -o +LABEL,PARTLABEL,UUID,PARTUUID}}<br />
<br />
In any case, the plain command without options should be enough to identify the drive you will install to (for example {{ic|1=/dev/sda}} or {{ic|1=/dev/nvme0n1}}:<br />
<br />
# lsblk<br />
<br />
=== Wipe Drive Securely (optional) ===<br />
<br />
While it is not necessary, given that this process will go through the trouble of encrypting the main system partition, it makes sense to do a secure wipe of the drive. This is more or less directly from [[Dm-crypt/Drive preparation#dm-crypt wipe on an empty disk or partition]].<br />
<br />
{{Warning|Be certain of your target device selection as we will be '''wiping this drive''' (either securely or, at minimum, destroying all existing partition data).}}<br />
<br />
First, create a temporary encrypted container the full disk ({{ic|sdX}}) to be encrypted, e.g. using default encryption parameters and a random key via the {{ic|--key-file /dev/{u}random}} option (see also [[Random number generation]]):<br />
<br />
# cryptsetup open --type plain /dev/sdXY container --key-file /dev/urandom<br />
<br />
{{Note|An interesting page addressing myths about /dev/urandom can be [http://www.2uo.de/myths-about-urandom/ found here]}}<br />
<br />
Second, check the container exists:<br />
<br />
{{hc|# fdisk -l|Disk /dev/mapper/container: XXXX MB, XXXXXXXXXX bytes<br />
...<br />
Disk /dev/mapper/container does not contain a valid partition table}}<br />
Wipe the container with zeros. A use of {{ic|1=if=/dev/urandom}} is '''not''' required as the encryption cipher itself generates randomness.<br />
{{hc|# dd <nowiki>if=/dev/zero of=/dev/mapper/container status=progress bs=1M</nowiki>|<br />
dd: writing to ‘/dev/mapper/container’: No space left on device}}<br />
<br />
{{Tip|<br />
* Using ''dd'' with the {{ic|1=bs=}} option, e.g. {{ic|1=bs=1M}} as above, is frequently used to increase disk throughput of the operation.<br />
* To perform a check of the operation, zero the partition before creating the wipe container. After the wipe command {{ic|blockdev --getsize64 ''/dev/mapper/container''}} can be used to get the exact container size as root. Now ''od'' can be used to spotcheck whether the wipe overwrote the zeroed sectors, e.g. {{ic|od -j ''containersize - blocksize''}} to view the wipe completed to the end.}}<br />
<br />
Finally, close the temporary container:<br />
<br />
# cryptsetup close container<br />
<br />
== Partition & Format Drive ==<br />
<br />
=== Understanding some basics about disks, partitions, and filesystems ===<br />
<br />
Think of your drive like a big empty building, no rooms. This is your plain physical drive (either a spinning platter drive or an SSD). Next imagine that to make it useful, we divide the building into apartments. In our analogy the apartments are '''partitions''' of the drive.<br />
<br />
Imagine also that there are a couple different standard methods of creating layout maps to the apartments. These plans are standardized so that the public services that have to access the building regularly (like the fire and police, for example) understand how to find the apartment entrances. In the world of partitioning, the equivalent is the "partition table scheme". The two common schemes are called "MBR" (Master Boot Record, older) and "GPT" (GUID Partition Table, newer). We will be using the new GPT scheme.<br />
<br />
Finally, imagine that the apartments are just empty shells. The act of building walls and laying out the functional structure of the apartments is equivalent to formatting our disk partitions with a filesystem. And just as different layouts may be more or less efficient, or have other different functional characteristics, so to filesystems have different attributes that make them useful in different ways.<br />
<br />
=== Our partition plans ===<br />
<br />
We will take our physical drive and divide it into three partitions. These partitions each serve a distinct purpose. All but the first and smallest, the EFI partition, will be encrypted. For security, if your system supports Secure Boot, you may choose to cryptographically sign the data stored on the EFI partition so that any tampering will be evident, despite the lack of encryption on that partition.<br />
<br />
{{Note|Again, we're assuming an UEFI installation (not legacy BIOS) and a GPT (not MBR) partition structure. If none of that made sense, best to start with the [[Partitioning]] article or do some test installs of Arch first. '''Partitioning is, in my opinion, one of the areas that is most confusing for the new Arch user.''' Additionally, there is a lot "received wisdom" and cargo-cult assumption making about how best to partition. Working through some of the "this is how it's always been done" tutorials isn't necessarily a bad thing... In many cases the way it has always been done has some sound reasoning behind it, despite being cargo-culted half the time. That being said, the method presented here is different from that in most of the Arch wiki partitioning methodologies.}}<br />
<br />
We will not be using LVM. You read a lot about LUKS and LVM and it all gets a bit complicated (LVM on LUKS, LUKS on LVM, etc.). LVM is a "logical volume manager" and abstracts physical devices (drives) into virtual devices, for easier management. It's a good idea but we will be using btrfs to effectively achieve the same results and really don't need the overhead of LVM.<br />
<br />
=== Partition Summary ===<br />
<br />
* 1: EFI - The UEFI 'bios" will look for this FAT32 formatted partition and either locate a default bootloader or will locate a specific EFI boot entry on it. This partition is by necessity not encrypted (unless the drive it is on has been encrypted as a "self encrypting drive")<br />
* 2: Swap - Used by Linux to swap out pages of memory from RAM to disk. Despite debate in this area, it is advisable to have at least some swap space, even it you are not planning on using hibernation on your machine. The Arch wiki is unfortunately rather too brief in its own [[Swap|swap article]] so I recommend the [https://docs.fedoraproject.org/en-US/Fedora/14/html/Storage_Administration_Guide/ch-swapspace.html Fedora documentation on swap] for a good overview on determining the right swap partition size.<br />
* 3: System - This will hold our root and home data. It will be formatted as BTRFS and will use subvolumes to manage snapshots of the current root and home contents.<br />
<br />
=== Visual overview of our partitions, filesystems, and contents ===<br />
<br />
This is a visual summary of our partions (inc. size information), encryption, filesystems, and a summary of the contents of each container.<br />
<br />
{| class="wikitable"<br />
| style="vertical-align: top; padding:1em" | '''Partition 1 (EFI)'''<br />
550MiB+<br />
{| style="border: 1px solid black; background: #DACEF2; margin: 1em;"<br />
! FAT32<br />
|-<br />
|kernel & initramfs<br />
(signed if using secure boot)<br />
|}<br />
| style="vertical-align: top; padding:1em" | '''Partition 2 (Swap)'''<br />
w/ Hibernate: Equal RAM,<br />
w/o Hibernate: min 8GB<br />
{| style="border: 1px solid black; background: #F2ECCE; margin: 1em;"<br />
|-<br />
! dm-crypt<br />
{| style="border: 1px solid black; background: #DACEF2; margin: 1em;"<br />
| SWAP<br />
|}<br />
|}<br />
| style="vertical-align: top; padding:1em" | '''Partition 3 (System)'''<br />
Remaining Space<br />
{| style="border: 1px solid black; background: #F2ECCE; margin: 1em;"<br />
|-<br />
! LUKS dm-crypt<br />
<br />
{| style="border: 1px solid black; background: #DACEF2; margin: 1em;"<br />
| BTRFS Top Level Subvolume<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Root Subvolume<br />
|}<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Home Subvolume<br />
|}<br />
<br />
{| style="border: 1px solid black; background: #E0CEF2; margin: 1em;"<br />
| BTRFS Snapshots Subvolume<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Root Snapshot Subvolume(s)<br />
|}<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Home Snapshot Subvolume(s)<br />
|}<br />
<br />
|}<br />
<br />
|}<br />
<br />
|}<br />
<br />
|}<br />
<br />
=== Partition Drive ===<br />
<br />
There are many utilities available for [[Partitioning]]. Because we are using Arch Linux and the command line doesn't hurt us (it makes us stronger) we will be using pure, non-interactive command line tools for this. Specifically, we will be using the utility [[Fdisk#Using_sgdisk|sgdisk]] from the {{Pkg|gptfdisk}} package. The [[Fdisk|fdisk]] utility now also supports GPT partitioned drives, so it would be an alternative. [[Fdisk#Using_sgdisk|sgdisk]] is available by default on the standard Arch install iso that you use to make your bootable USB drive.<br />
<br />
First, select the drive you will install to. Make sure you have selected the correct drive!. Again, a quick {{ic|lsblk}} will work here.<br />
<br />
# DRIVE=/dev/DRIVEID<br />
<br />
(replace /dev/DRIVEID with the correct value, for example /dev/sda, /dev/nvme0n1, etc.)<br />
<br />
If you didn't securely wipe the drive already, it's worth "zapping" it using [[Fdisk#Using_sgdisk|sgdisk]] to remove any lingering legacy partition information. If you already wiped the drive you can skip this command (though it won't hurt to run it again).<br />
<br />
{{Warning|'''This command will also effectively erase the selected drive!'''}}<br />
<br />
# sgdisk --zap-all $DRIVE<br />
<br />
The following command will then create all three partitions in one go. '''It will also effectively erase the selected drive!'''<br />
<br />
# sgdisk --clear \<br />
--new=1:0:+550MiB --typecode=1:ef00 --change-name=1:EFI \<br />
--new=2:0:+8GiB --typecode=2:8200 --change-name=2:cryptswap \<br />
--new=3:0:0 --typecode=2:8200 --change-name=3:cryptsystem \<br />
$DRIVE<br />
<br />
It is worth noting that the "--change-name" values are, in this case, creating GPT "partition labels". You can subsequently see these by using the {{ic|lsblk -o +PARTLABEL}} command. It is good to use "EFI" for the efi partition. I am not aware of UEFI implementations that actively use the label for identification of the EFI partition, but it is possible that some do (UEFI bios implementations are not always consistent or to spec). The other two names are entirely "arbitrary". There is nothing special about calling them cryptswap and cryptsystem; they are simply good, clear names that remind us of the purpose of this partition and what it contains (for example, "cryptswap" suggests "this partition is for swap, and is encrypted").<br />
<br />
One final note about partition labels: we want them to be unique on your system. If for some reason there is already a GPT partition with the name EFI on another drive on your system, either change that partition name or use something besides "EFI" to avoid a namespace collision.<br />
<br />
Note also, that the backslashes at the end of each line can be omitted if you are writing the command on one long line instead. Those simply allow the splitting of a single command onto multiple lines.<br />
<br />
=== Format EFI Partition ===<br />
<br />
Next up: format the first (EFI) partition using the (required) FAT32 filesystem.<br />
<br />
# mkfs.fat -F32 -n EFI /dev/disk/by-partlabel/EFI<br />
<br />
Note that we here make use of the partition label we just assigned. I prefer doing this since it simplifies scripts significantly for me and makes them, in my opinion, more readable.<br />
<br />
=== Encrypt System Partition ===<br />
<br />
Encrypt the main partition. Use a good passphrase. Note that the "--align-payload" value has been used as per [http://www.spinics.net/lists/dm-crypt/msg02421.html this suggestion/explanation] on the dm-crypt mailing list.<br />
<br />
Note also that I selected the encryption algorithm and key size using cryptsetup benchmark. See the [[Dm-crypt/Device_encryption]] article for more details.<br />
<br />
# cryptsetup luksFormat --align-payload=8192 -s 256 -c aes-xts-plain64 /dev/disk/by-partlabel/cryptsystem<br />
<br />
After creating the encrypted container, open it. Again, note the use of the partition label to identify the drive. Additionally, note that once we open this device we are giving it a name of "system." Thus "cryptsystem" is the encrypted system partition, while "system" is the name we are using once it has been opened in an unencrypted state. These names are arbitrary (Linux doesn't care what we use) but they help us keep things organized during this process.<br />
<br />
# cryptsetup open /dev/disk/by-partlabel/cryptsystem system<br />
<br />
=== Bring Up Encrypted Swap ===<br />
<br />
Finally we create encrypted swap. In this example we are not enabling hibernation. I will provide information on how to enable hibernation separately. Again, using partition labels to identify the partition and going from "cryptswap" to just "swap".<br />
<br />
We are not using LUKS here (which effectively makes dm-crypt easier to use). We're just using plain dm-crypt to encrypt the swap partition using a random key.<br />
<br />
# cryptsetup open --type plain --key-file /dev/urandom /dev/disk/by-partlabel/cryptswap swap<br />
# mkswap -L swap /dev/mapper/swap<br />
# swapon -L swap<br />
<br />
=== Create and mount BTRFS subvolumes ===<br />
<br />
Now on to the main attraction: creating our BTRFS subvolume structure. While BTRFS can be set up like any other filesystem (single command, just use the created file system directly), we're going to use the power of BTRFS to enable snapshotting our system state efficiently and rollbacks as necessary.<br />
<br />
First we create a top-level BTRFS subvolume. Note that the top-level entity in BTRFS nomenclature is still referred to as a '''sub'''volume, despite being at the top-level.<br />
<br />
We will create and mount this subvolume, create some new subvolumes inside it, and then switch to those subvolumes as our proper, mounted filesystems. Doing this will enable us to treat our root filesystem as a snapshotable object.<br />
<br />
Top-level subvolume creation.<br />
<br />
# mkfs.btrfs --force --label system /dev/mapper/system<br />
<br />
Temporarily mount our top-level volume for further subvolume creation. Note that the variable 'o' in this case is our default set of options for any given filesystem mount, while "o_btrfs" are those plus some options specific to btrfs. The default option "x-mount.mkdir" is a neat trick that allows us to skip the creation of directories for mountpoints (they will be created automatically). We assume /mnt as the standard mount point, as in a normal Arch Linux installation.<br />
<br />
# o=defaults,x-mount.mkdir<br />
# o_btrfs=$o,compress=lzo,ssd,noatime<br />
<br />
Note the use of our filesystem label to mount our subvolume. This is distinct from the partition labels used earlier. See the Arch wiki article on [[Persistent_block_device_naming]] for more information.<br />
<br />
# mount -t btrfs LABEL=system /mnt<br />
<br />
Now we create the subvolumes which will actually be mounted in our running system:<br />
<br />
# btrfs subvolume create /mnt/root<br />
# btrfs subvolume create /mnt/home<br />
# btrfs subvolume create /mnt/snapshots<br />
<br />
Then we unmount everything...<br />
<br />
# umount -R /mnt<br />
<br />
And remount just the subvolumes under our top-level subvolume (which remains unmounted unless we need to do "surgery" and rollback to a previous system system):<br />
<br />
# mount -t btrfs -o subvol=root,$o_btrfs LABEL=system /mnt<br />
<br />
Before mounting the home and snapshots subvolumes, let's walk through that command so we understand what it's doing:<br />
<br />
The 'mount -t btrfs' just specifies that our filesystem is of type BTRFS. This is often not necessary since mount will attempt to identify the filesystem type, but being explicit is often the best strategy with command line utilities, so we identify the type here.<br />
<br />
We use our previously defined mount options with the $o_btrfs variable and add the additional option "subvol=root" (separating it from our other defaults with a comma, of course). The next part of the command is "LABEL=system". Combined this reads as "mount the filesystem with the 'system' label, and use the 'root' subvolume within that".<br />
<br />
Finally, all this gets mounted at our install root, which in this case is "/mnt".<br />
<br />
Now let's pick back up and mount our home and snapshots subvolumes. Note that while the subvolume name is "snapshots", we will mount it at ".snapshots" (note dot prefix for the mount point). This will keep our root directory listing clean but will still make it available at a reasonable mount location.<br />
<br />
# mount -t btrfs -o subvol=home,$o_btrfs LABEL=system /mnt/home<br />
# mount -t btrfs -o subvol=snapshots,$o_btrfs LABEL=system /mnt/.snapshots<br />
<br />
It it worth noting that in each case we are telling mount to use the same filesystem, namely the one labeled "system". However in each case we are also telling it to look for a different subvolume in that filesystem (via the "subvol=" option).<br />
<br />
With this done, we can move on to installing the actual system.<br />
<br />
=== Mount EFI partition ===<br />
<br />
# mount LABEL=EFI /mnt/boot<br />
<br />
== Installation of Base Arch Linux System ==<br />
<br />
We are currently running off the Arch installer root filesystem. We will first use the 'pacstrap' utility to start our installation and then we will boot into our new minimal system using systemd-nspawn.<br />
<br />
=== Install base package group ===<br />
<br />
# pacstrap /mnt base<br />
<br />
=== fstab Generation and Modification ===<br />
<br />
{{Note|In a simpler, non encrypted configuration it is possible to skip making an fstab altogether due to a standard known as the [https://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/ Discoverable Partitions Spec]. However given the complexity of our encrypted, btrfs subvolume configuration, we require an fstab at this time. It is possible that in future we might feasibly do away with the fstab almost entirely in this setup (see the [https://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/#whataboutautomaticmountingofbtrfssubvolumestovarhomeandsoon 'What about automatic mounting of btrfs subvolumes'] section on that page).}}<br />
<br />
Create an [[fstab]] filesystem table file, using labels (-L) to identify the filesystems.<br />
<br />
# genfstab -L -p /mnt >> /mnt/etc/fstab<br />
<br />
I prefer to use labels as this makes the system more portable to a backup drive. You should end up with something that looks pretty close to this:<br />
<br />
{{hc|# cat /mnt/etc/fstab|<nowiki><br />
# /dev/mapper/system UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=system / btrfs rw,noatime,compress=lzo,ssd,space_cache,subvolid=257,subvol=/root,subvol=root 0 0<br />
<br />
# /dev/mapper/system UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=system /home btrfs rw,noatime,compress=lzo,ssd,space_cache,subvolid=258,subvol=/home,subvol=home 0 0<br />
<br />
# /dev/mapper/system UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=system /.snapshots btrfs rw,noatime,compress=lzo,ssd,space_cache,subvolid=259,subvol=/snapshots,subvol=snapshots 0 0<br />
<br />
# /dev/nvme0n1p1 UUID=xxxx-xxxx<br />
LABEL=EFI /boot/EFI vfat rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro 0 2<br />
<br />
# /dev/mapper/swap UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=swap none swap defaults 0 0<br />
</nowiki>}}<br />
<br />
There is one problem, however. Swap will not remount this way (the plain dm-crypt partition with a random key will not have a label when it is recreated on reboot). You will have to change that line from this:<br />
<br />
{{bc|<nowiki>LABEL=swap none swap defaults 0 0</nowiki>}}<br />
<br />
to this:<br />
<br />
{{bc|/dev/mapper/swap none swap defaults 0 0}}<br />
<br />
This will ensure that the mapped device is opened as swap successfully. The other lines may remain unchanged.<br />
<br />
==== Use {{ic|sed}} instead ====<br />
<br />
As a (scriptable) alternative to the manual editing of your {{ic|/etc/fstab}} you could use {{Man|1|sed}} to edit the file in place:<br />
<br />
# sed -i s+LABEL=swap+/dev/mapper/swap+ /mnt/etc/fstab_labels<br />
<br />
=== Boot into new system ===<br />
<br />
{{Warning|While this works, I am fairly certain I'll want to double check some things before declaring this step final. Specifically I want to consider some bind mounts and whether there is anything that should be r/w instead of r/o as is normal in a systemd-nspawn container.}}<br />
<br />
# systemd-nspawn -bD /mnt<br />
<br />
This will boot your new base Arch Linux system. After the standard boot messages scroll by you will be presented with a login (enter {{ic|root}} and hit enter to login).<br />
<br />
=== Generate and set locale ===<br />
<br />
Next, edit and uncomment your desired locale(s) from {{ic|/etc/locale.gen}}. We use {{ic|vi}} in the example below, but you could use a simpler editor such as {{ic|nano}} if you wish.<br />
<br />
{{hc|vi /etc/locale.gen|<nowiki><br />
...<br />
#en_PH.UTF-8 UTF-8<br />
#en_PH ISO-8859-1<br />
#en_SG.UTF-8 UTF-8<br />
#en_SG ISO-8859-1<br />
#en_US.UTF-8 UTF-8<br />
#en_US ISO-8859-1<br />
#en_ZA.UTF-8 UTF-8<br />
#en_ZA ISO-8859-1<br />
#en_ZM UTF-8<br />
...<br />
</nowiki>}}<br />
<br />
Changing it to (for en_US.UTF-8 as a locale in this example):<br />
<br />
{{bc|<nowiki><br />
...<br />
#en_PH.UTF-8 UTF-8<br />
#en_PH ISO-8859-1<br />
#en_SG.UTF-8 UTF-8<br />
#en_SG ISO-8859-1<br />
en_US.UTF-8 UTF-8<br />
#en_US ISO-8859-1<br />
#en_ZA.UTF-8 UTF-8<br />
#en_ZA ISO-8859-1<br />
#en_ZM UTF-8<br />
...<br />
</nowiki>}}<br />
<br />
Alternately one could simply append a known value to the {{ic|/etc/locale.gen}} file:<br />
<br />
# echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen<br />
<br />
After either method, one runs the {{ic|locale-gen}} command to generate the locale files:<br />
<br />
# locale-gen<br />
<br />
Finally we use {{Man|1|systemd-firstboot}} or {{Man|1|localectl}} to set the system locale. Each of these effectively does the same thing which is to simply write to {{ic|/etc/locale.conf}} (which can simply be edited directly as per standard Arch install instructions).<br />
<br />
==== With systemd-firstboot ====<br />
<br />
{{Man|1|systemd-firstboot}} will prompt us for selection from our generated locales. It will only work if there is no assigned system locale. If you wish to make changes afterward you can use {{Man|1|localectl}}<br />
<br />
# systemd-firstboot --prompt-locale<br />
<br />
==== With localectl ====<br />
<br />
This is an alternate to using {{ic|systemd-firstboot --prompt-locale}}. It may also be used subsequent to that command if further changes to the locale are desired.<br />
<br />
If you need a reminder of which locales have been installed (during this install or later during system changes), use {{ic|localectl list-locales}}:<br />
<br />
{{hc|<nowiki># localectl list-locales</nowiki>|en_US.UTF-8}}<br />
<br />
We then use {{ic|localectl set-locale}}:<br />
<br />
# localectl set-locale LANG=en_US.UTF-8<br />
<br />
=== Time and Date ===<br />
<br />
Unless you have a reason not to, we'll turn on NTP synchronization.<br />
<br />
# timedatectl set-ntp 1<br />
<br />
Then list timezones and pick one<br />
<br />
{{hc|<nowiki># timedatectl list-timezones</nowiki>|<nowiki><br />
...<br />
America/Kentucky/Louisville<br />
America/Kentucky/Monticello<br />
America/Kralendijk<br />
America/La_Paz<br />
America/Lima<br />
America/Los_Angeles<br />
America/Lower_Princes<br />
America/Maceio<br />
America/Managua<br />
America/Manaus<br />
America/Marigot<br />
America/Martinique<br />
America/Matamoros<br />
...<br />
</nowiki>}}<br />
# timedatectl set-timezone America/Los_Angeles<br />
<br />
=== Set hostname ===<br />
<br />
# hostnamectl set-hostname myhostname<br />
<br />
See the man page for {{Man|1|hostnamectl}} for other attributes that can be set. You might also add the hostname to {{Man|5|hosts}}:<br />
<br />
{{hc|/etc/hosts|<br />
127.0.0.1 localhost.localdomain localhost<br />
::1 localhost.localdomain localhost<br />
'''127.0.1.1 ''myhostname''.localdomain ''myhostname'''''<br />
}}<br />
<br />
Use {{ic|echo}} for a scriptable solution:<br />
<br />
# echo "127.0.1.1 myhostname.localdomain myhostname" >> /etc/hosts<br />
<br />
=== Network configuration ===<br />
<br />
Configure the network for the newly installed environment: see [[Network configuration]].<br />
<br />
For [[Wireless configuration]], [[Help:Reading#Installation of packages|install]] the {{Pkg|iw}}, {{Pkg|wpa_supplicant}}, and {{Pkg|dialog}} packages, as well as needed [[Wireless#Installing driver/firmware|firmware packages]].<br />
<br />
=== Base Package Installation ===<br />
<br />
We've already included the {{Grp|base}} group which is, strictly speaking, all you need to boot a minimal Arch Linux system. At this stage, however, we can install some useful utilities (and Xorg or Wayland, etc.).<br />
<br />
# pacman -Syu base-devel btrfs-progs iw gptfdisk zsh vim terminus-font<br />
<br />
=== Initramfs ===<br />
<br />
Creating a new ''initramfs'' is usually not required, because [[mkinitcpio]] was run on installation of the {{Pkg|linux}} package with ''pacstrap''. However we'll need to make some changes to the hooks used on our system. Additionally, I switched over to using the systemd hooks in mkinitcpio, so that is largely what you'll see in my example below.<br />
<br />
I recommend making a backup of your {{ic|/etc/mkinitcpio.conf}} file first:<br />
<br />
# mv /etc/mkinitcpio.conf /etc/mkinitcpio.conf.orig<br />
<br />
and then editing a new file to match the following contents:<br />
<br />
{{bc|<nowiki><br />
MODULES=""<br />
BINARIES=""<br />
FILES=""<br />
HOOKS="base systemd sd-vconsole modconf keyboard block filesystems btrfs sd-encrypt fsck"<br />
</nowiki>}}<br />
<br />
Finally, recreate the initramfs image:<br />
<br />
# mkinitcpio -p linux<br />
<br />
=== Bootloader ===<br />
<br />
{{Warning|THIS SECTION IN PROGRESS}}<br />
<br />
=== Root password ===<br />
<br />
Set the root [[password]]:<br />
<br />
# passwd<br />
<br />
=== Leave the systemd-nspawn environment ===<br />
<br />
Issue a poweroff to exit the nspawned environment:<br />
<br />
# poweroff<br />
<br />
This will return you the Arch installer environment where you can wrap up.<br />
<br />
=== Legacy boot loader ===<br />
<br />
If your system is not UEFI and you need to use a legacy installer like grub, it will need to be installed from within an arch-chroot generated chroot, not the systemd-nspawn running container. An example of this would be (assuming that the drive of the new system is at /dev/sdb):<br />
<br />
# arch-chroot /mnt<br />
# grub-install $DRIVE<br />
# grub-mkconfig -o /boot/grub/grub.cfg<br />
# exit<br />
<br />
== Command Summary ==<br />
<br />
The following are all critical commands (exluded: the initial drive wipe which is optional). It assumes you have successfully brought up networking prior to starting this sequence.<br />
<br />
{{bc|<nowiki><br />
<br />
DRIVE=/dev/DRIVEID<br />
<br />
sgdisk --zap-all $DRIVE<br />
<br />
sgdisk --clear \<br />
--new=1:0:+550MiB --typecode=1:ef00 --change-name=1:EFI \<br />
--new=2:0:+8GiB --typecode=2:8200 --change-name=2:cryptswap \<br />
--new=3:0:0 --typecode=2:8200 --change-name=3:cryptsystem \<br />
$DRIVE<br />
<br />
mkfs.fat -F32 -n EFI /dev/disk/by-partlabel/EFI<br />
<br />
cryptsetup luksFormat --align-payload=8192 -s 256 -c aes-xts-plain64 /dev/disk/by-partlabel/cryptsystem<br />
<br />
cryptsetup open /dev/disk/by-partlabel/cryptsystem system<br />
<br />
cryptsetup open --type plain --key-file /dev/urandom /dev/disk/by-partlabel/cryptswap swap<br />
<br />
mkswap -L swap /dev/mapper/swap<br />
<br />
swapon -L swap<br />
<br />
mkfs.btrfs --force --label system /dev/mapper/system<br />
<br />
o=defaults,x-mount.mkdir<br />
<br />
o_btrfs=$o,compress=lzo,ssd,noatime<br />
<br />
mount -t btrfs LABEL=system /mnt<br />
<br />
btrfs subvolume create /mnt/root<br />
<br />
btrfs subvolume create /mnt/home<br />
<br />
btrfs subvolume create /mnt/snapshots<br />
<br />
umount -R /mnt<br />
<br />
mount -t btrfs -o subvol=root,$o_btrfs LABEL=system /mnt<br />
<br />
mount -t btrfs -o subvol=home,$o_btrfs LABEL=system /mnt/home<br />
<br />
mount -t btrfs -o subvol=snapshots,$o_btrfs LABEL=system /mnt/.snapshots<br />
<br />
pacstrap /mnt base<br />
<br />
genfstab -L -p /mnt >> /mnt/etc/fstab<br />
<br />
sed -i "s+LABEL=swap+/dev/mapper/swap" /etc/fstab_labels<br />
<br />
systemd-nspawn -bD /mnt<br />
<br />
echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen<br />
<br />
locale-gen<br />
<br />
localectl set-locale LANG=en_US.UTF-8<br />
<br />
timedatectl set-ntp 1<br />
<br />
timedatectl set-timezone America/Los_Angeles<br />
<br />
hostnamectl set-hostname myhostname<br />
<br />
echo "127.0.1.1 myhostname.localdomain myhostname" >> /etc/hosts<br />
<br />
pacman -Syu base-devel btrfs-progs iw gptfdisk zsh vim terminus-font<br />
</nowiki>}}<br />
<br />
== Quick and Dirty ==<br />
<br />
{{Note|an extra example and may be moved to its own wiki page later}}<br />
<br />
This is the approximate process I follow if I want to bring up Arch on, say, an old laptop for a quick purpose built test machine, etc. It's not an install that I consider long term maintainable since rollbacks aren't implemented, nor is there any encryption, but it's a good example of how simple installation can be.<br />
<br />
{{bc|<nowiki><br />
DRIVE=/dev/DRIVEID<br />
sgdisk --zap-all $DRIVE<br />
mkfs.btrfs -f $DRIVE<br />
mount -t btrfs $DRIVE /mnt<br />
pacstrap /mnt base grub<br />
systemd-nspawn -bD /mnt<br />
echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen<br />
locale-gen<br />
localectl set-locale LANG=en_US.UTF-8<br />
timedatectl set-ntp 1<br />
timedatectl set-timezone America/Los_Angeles<br />
hostnamectl set-hostname myhostname<br />
poweroff<br />
arch-chroot /mnt<br />
grub-install --root-directory=/mnt $DRIVE<br />
grub-mkconfig -o /mnt/boot/grub/grub.cfg<br />
exit<br />
reboot<br />
</nowiki>}}</div>Altercationhttps://wiki.archlinux.org/index.php?title=User:Altercation/Bullet_Proof_Arch_Install&diff=458973User:Altercation/Bullet Proof Arch Install2016-12-10T18:07:20Z<p>Altercation: /* Quick and Dirty */</p>
<hr />
<div>This page is a summary of the current process I follow when installing Arch on a new laptop or desktop. My process varies over time, but this serves as my "state of the art" best practice recommendations. I'm open to feedback and suggestions for improvements.<br />
<br />
{{Note|This is entirely based on my own opinions and research. It is opinionated about the best way to do things given the current state of the kernel, hardware availability, and utilities, filesystems, etc. I will explain my rationale for specific choices and provide links to other sources of information (on the Arch wiki or external) where useful.}}<br />
<br />
== Objectives ==<br />
<br />
The goals of my standard "bullet proof" Arch Linux installation are:<br />
<br />
* Benefit from Arch's rolling release model while mitigating any risk of system corruption or data loss due to failed upgrades<br />
* Minimize risk due to hardware failure or total system loss (e.g. theft or physical destruction)<br />
* Make system rollbacks easy and procedural, using a standard setup and methodology for recovery of previous system (and user data) states<br />
<br />
=== Why not the Arch Install instructions? ===<br />
<br />
The [[Installation guide|Arch Linux installation instructions]] are an excellent, general starting point and you should read and understand them. That being said, they are designed to map to a very, very broad set of installation scenarios. I am interested in a very specific type of installation (daily use desktops and laptops in this article) and I have a strong set of opinions about the "right" or "best practice" way to set up my own working systems.<br />
<br />
These instructions, then, are much more prescriptive and have strong suggestions or directions about how (and why) one should use a particular method during Arch Linux installation.<br />
<br />
=== Key differences from the stock Arch install instructions ===<br />
<br />
How these instructions differ from the standard Arch guidance:<br />
<br />
* We are encrypting the entire system but not using LVM as is often recommended (see the encryption section below for details about why we are not using it).<br />
* I use labels and avoid UUIDs where possible to make switching to an alternate recovery drive easier.<br />
* I skip arch-chroot and simply boot the new system ('''not''' reboot, just boot) from within the install environment using {{Man|1|systemd-nspawn}} which enables the *ctl commands to work (and systemd services to be enabled properly without need for a system reboot)<br />
* I use the various systemd *ctl commands (hostnamectl, timedatectl, localectl, etc.) to configure the system<br />
* I use the systemd mkinitcpio hooks in lieu of the legacy hooks.<br />
* I use BTRFS exclusively for root and home partitions for its backup capabilities.<br />
* I recommend and use secure boot (but not with the Microsoft keys) to minimize risk due to the unavoidably unencrypted EFI partition.<br />
<br />
== Assumptions ==<br />
<br />
These instructions presuppose the following:<br />
<br />
* fairly new hardware (these instructions may work on older hardware, but there may be unusual issues that crop up... if you aren't comfortable handling those situations you should consider a more "traditional" Arch Linux install (e.g. using grub, LVM, ext4, etc.)<br />
* [[Unified Extensible Firmware Interface|UEFI support]] (BIOS system install is also possible with some modification of these instructions, but this has not yet been detailed here)<br />
* probably an [[Solid State Drives|SSD]].<br />
* some familiarity with Arch, or at least some experience with Linux, will help<br />
<br />
{{Warning|I am assuming you are going to single boot (not dual boot) and that you are '''willing to wipe all data from the install drive.''' If that is not the case, do not proceed with these instructions as following them '''will effectively destroy any data (and other operating systems) on the installation target drive.'''}}<br />
<br />
== Prerequisites ==<br />
<br />
You must have a recent copy of the Arch install USB. See [[:Category:Getting and installing Arch]] for general information and [[USB flash installation media]] for specific details on creating a USB Arch installation drive.<br />
<br />
You should also have a reasonable amount of time in which to complete the installation. Novice users will want to budget a couple hours. Experienced users will ''know'' to budget a couple hours.<br />
<br />
== Preparation ==<br />
<br />
=== Boot from USB Drive ===<br />
<br />
Boot your system from your prepared [[USB flash installation media|Arch Linux USB drive]]. It is important that you boot in EFI mode, not legacy BIOS compatibility mode. See the [[Unified Extensible Firmware Interface|UEFI]] article for more information about checking boot mode and ensuring you are booting using EFI.<br />
<br />
=== Bring up the network ===<br />
<br />
If you booted into a system with an ethernet cable plugged in, chances are you're up and running. If you need to use wireless instead, {{ic|wifi-menu}} will more often than not work without trouble. If those don't work, see [[Installation guide#Connect to the Internet|the Arch installation guide section on connecting to the internet]].<br />
<br />
=== Select Drive ===<br />
<br />
I like to use the [[Core utilities#lsblk|{{ic|1=lsblk}}]] command to bring up a quick list of the block devices on the system and identify existing partition structures and sizes, as well as mount points. If you don't already use it, I recommend [[Core utilities#lsblk|{{ic|1=lsblk}}]] when you need information on any given drive or partition. It's useful for polling UUIDs as well. For example, the following command gives you a clearly formatted summary of all block devices, their partition labels, filesystem lables, UUIDs and partition UUIDS: {{ic|lsblk -o +LABEL,PARTLABEL,UUID,PARTUUID}}<br />
<br />
In any case, the plain command without options should be enough to identify the drive you will install to (for example {{ic|1=/dev/sda}} or {{ic|1=/dev/nvme0n1}}:<br />
<br />
# lsblk<br />
<br />
=== Wipe Drive Securely (optional) ===<br />
<br />
While it is not necessary, given that this process will go through the trouble of encrypting the main system partition, it makes sense to do a secure wipe of the drive. This is more or less directly from [[Dm-crypt/Drive preparation#dm-crypt wipe on an empty disk or partition]].<br />
<br />
{{Warning|Be certain of your target device selection as we will be '''wiping this drive''' (either securely or, at minimum, destroying all existing partition data).}}<br />
<br />
First, create a temporary encrypted container the full disk ({{ic|sdX}}) to be encrypted, e.g. using default encryption parameters and a random key via the {{ic|--key-file /dev/{u}random}} option (see also [[Random number generation]]):<br />
<br />
# cryptsetup open --type plain /dev/sdXY container --key-file /dev/urandom<br />
<br />
{{Note|An interesting page addressing myths about /dev/urandom can be [http://www.2uo.de/myths-about-urandom/ found here]}}<br />
<br />
Second, check the container exists:<br />
<br />
{{hc|# fdisk -l|Disk /dev/mapper/container: XXXX MB, XXXXXXXXXX bytes<br />
...<br />
Disk /dev/mapper/container does not contain a valid partition table}}<br />
Wipe the container with zeros. A use of {{ic|1=if=/dev/urandom}} is '''not''' required as the encryption cipher itself generates randomness.<br />
{{hc|# dd <nowiki>if=/dev/zero of=/dev/mapper/container status=progress bs=1M</nowiki>|<br />
dd: writing to ‘/dev/mapper/container’: No space left on device}}<br />
<br />
{{Tip|<br />
* Using ''dd'' with the {{ic|1=bs=}} option, e.g. {{ic|1=bs=1M}} as above, is frequently used to increase disk throughput of the operation.<br />
* To perform a check of the operation, zero the partition before creating the wipe container. After the wipe command {{ic|blockdev --getsize64 ''/dev/mapper/container''}} can be used to get the exact container size as root. Now ''od'' can be used to spotcheck whether the wipe overwrote the zeroed sectors, e.g. {{ic|od -j ''containersize - blocksize''}} to view the wipe completed to the end.}}<br />
<br />
Finally, close the temporary container:<br />
<br />
# cryptsetup close container<br />
<br />
== Partition & Format Drive ==<br />
<br />
=== Understanding some basics about disks, partitions, and filesystems ===<br />
<br />
Think of your drive like a big empty building, no rooms. This is your plain physical drive (either a spinning platter drive or an SSD). Next imagine that to make it useful, we divide the building into apartments. In our analogy the apartments are '''partitions''' of the drive.<br />
<br />
Imagine also that there are a couple different standard methods of creating layout maps to the apartments. These plans are standardized so that the public services that have to access the building regularly (like the fire and police, for example) understand how to find the apartment entrances. In the world of partitioning, the equivalent is the "partition table scheme". The two common schemes are called "MBR" (Master Boot Record, older) and "GPT" (GUID Partition Table, newer). We will be using the new GPT scheme.<br />
<br />
Finally, imagine that the apartments are just empty shells. The act of building walls and laying out the functional structure of the apartments is equivalent to formatting our disk partitions with a filesystem. And just as different layouts may be more or less efficient, or have other different functional characteristics, so to filesystems have different attributes that make them useful in different ways.<br />
<br />
=== Our partition plans ===<br />
<br />
We will take our physical drive and divide it into three partitions. These partitions each serve a distinct purpose. All but the first and smallest, the EFI partition, will be encrypted. For security, if your system supports Secure Boot, you may choose to cryptographically sign the data stored on the EFI partition so that any tampering will be evident, despite the lack of encryption on that partition.<br />
<br />
{{Note|Again, we're assuming an UEFI installation (not legacy BIOS) and a GPT (not MBR) partition structure. If none of that made sense, best to start with the [[Partitioning]] article or do some test installs of Arch first. '''Partitioning is, in my opinion, one of the areas that is most confusing for the new Arch user.''' Additionally, there is a lot "received wisdom" and cargo-cult assumption making about how best to partition. Working through some of the "this is how it's always been done" tutorials isn't necessarily a bad thing... In many cases the way it has always been done has some sound reasoning behind it, despite being cargo-culted half the time. That being said, the method presented here is different from that in most of the Arch wiki partitioning methodologies.}}<br />
<br />
We will not be using LVM. You read a lot about LUKS and LVM and it all gets a bit complicated (LVM on LUKS, LUKS on LVM, etc.). LVM is a "logical volume manager" and abstracts physical devices (drives) into virtual devices, for easier management. It's a good idea but we will be using btrfs to effectively achieve the same results and really don't need the overhead of LVM.<br />
<br />
=== Partition Summary ===<br />
<br />
* 1: EFI - The UEFI 'bios" will look for this FAT32 formatted partition and either locate a default bootloader or will locate a specific EFI boot entry on it. This partition is by necessity not encrypted (unless the drive it is on has been encrypted as a "self encrypting drive")<br />
* 2: Swap - Used by Linux to swap out pages of memory from RAM to disk. Despite debate in this area, it is advisable to have at least some swap space, even it you are not planning on using hibernation on your machine. The Arch wiki is unfortunately rather too brief in its own [[Swap|swap article]] so I recommend the [https://docs.fedoraproject.org/en-US/Fedora/14/html/Storage_Administration_Guide/ch-swapspace.html Fedora documentation on swap] for a good overview on determining the right swap partition size.<br />
* 3: System - This will hold our root and home data. It will be formatted as BTRFS and will use subvolumes to manage snapshots of the current root and home contents.<br />
<br />
=== Visual overview of our partitions, filesystems, and contents ===<br />
<br />
This is a visual summary of our partions (inc. size information), encryption, filesystems, and a summary of the contents of each container.<br />
<br />
{| class="wikitable"<br />
| style="vertical-align: top; padding:1em" | '''Partition 1 (EFI)'''<br />
550MiB+<br />
{| style="border: 1px solid black; background: #DACEF2; margin: 1em;"<br />
! FAT32<br />
|-<br />
|kernel & initramfs<br />
(signed if using secure boot)<br />
|}<br />
| style="vertical-align: top; padding:1em" | '''Partition 2 (Swap)'''<br />
w/ Hibernate: Equal RAM,<br />
w/o Hibernate: min 8GB<br />
{| style="border: 1px solid black; background: #F2ECCE; margin: 1em;"<br />
|-<br />
! dm-crypt<br />
{| style="border: 1px solid black; background: #DACEF2; margin: 1em;"<br />
| SWAP<br />
|}<br />
|}<br />
| style="vertical-align: top; padding:1em" | '''Partition 3 (System)'''<br />
Remaining Space<br />
{| style="border: 1px solid black; background: #F2ECCE; margin: 1em;"<br />
|-<br />
! LUKS dm-crypt<br />
<br />
{| style="border: 1px solid black; background: #DACEF2; margin: 1em;"<br />
| BTRFS Top Level Subvolume<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Root Subvolume<br />
|}<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Home Subvolume<br />
|}<br />
<br />
{| style="border: 1px solid black; background: #E0CEF2; margin: 1em;"<br />
| BTRFS Snapshots Subvolume<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Root Snapshot Subvolume(s)<br />
|}<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Home Snapshot Subvolume(s)<br />
|}<br />
<br />
|}<br />
<br />
|}<br />
<br />
|}<br />
<br />
|}<br />
<br />
=== Partition Drive ===<br />
<br />
There are many utilities available for [[Partitioning]]. Because we are using Arch Linux and the command line doesn't hurt us (it makes us stronger) we will be using pure, non-interactive command line tools for this. Specifically, we will be using the utility [[Fdisk#Using_sgdisk|sgdisk]] from the {{Pkg|gptfdisk}} package. The [[Fdisk|fdisk]] utility now also supports GPT partitioned drives, so it would be an alternative. [[Fdisk#Using_sgdisk|sgdisk]] is available by default on the standard Arch install iso that you use to make your bootable USB drive.<br />
<br />
First, select the drive you will install to. Make sure you have selected the correct drive!. Again, a quick {{ic|lsblk}} will work here.<br />
<br />
# $DRIVE=/dev/DRIVEID<br />
<br />
(replace /dev/DRIVEID with the correct value, for example /dev/sda, /dev/nvme0n1, etc.)<br />
<br />
If you didn't securely wipe the drive already, it's worth "zapping" it using [[Fdisk#Using_sgdisk|sgdisk]] to remove any lingering legacy partition information. If you already wiped the drive you can skip this command (though it won't hurt to run it again).<br />
<br />
{{Warning|'''This command will also effectively erase the selected drive!'''}}<br />
<br />
# sgdisk --zap-all $DRIVE<br />
<br />
The following command will then create all three partitions in one go. '''It will also effectively erase the selected drive!'''<br />
<br />
# sgdisk --clear \<br />
--new=1:0:+550MiB --typecode=1:ef00 --change-name=1:EFI \<br />
--new=2:0:+8GiB --typecode=2:8200 --change-name=2:cryptswap \<br />
--new=3:0:0 --typecode=2:8200 --change-name=3:cryptsystem \<br />
$DRIVE<br />
<br />
It is worth noting that the "--change-name" values are, in this case, creating GPT "partition labels". You can subsequently see these by using the {{ic|lsblk -o +PARTLABEL}} command. It is good to use "EFI" for the efi partition. I am not aware of UEFI implementations that actively use the label for identification of the EFI partition, but it is possible that some do (UEFI bios implementations are not always consistent or to spec). The other two names are entirely "arbitrary". There is nothing special about calling them cryptswap and cryptsystem; they are simply good, clear names that remind us of the purpose of this partition and what it contains (for example, "cryptswap" suggests "this partition is for swap, and is encrypted").<br />
<br />
One final note about partition labels: we want them to be unique on your system. If for some reason there is already a GPT partition with the name EFI on another drive on your system, either change that partition name or use something besides "EFI" to avoid a namespace collision.<br />
<br />
Note also, that the backslashes at the end of each line can be omitted if you are writing the command on one long line instead. Those simply allow the splitting of a single command onto multiple lines.<br />
<br />
=== Format EFI Partition ===<br />
<br />
Next up: format the first (EFI) partition using the (required) FAT32 filesystem.<br />
<br />
# mkfs.fat -F32 -n EFI /dev/disk/by-partlabel/EFI<br />
<br />
Note that we here make use of the partition label we just assigned. I prefer doing this since it simplifies scripts significantly for me and makes them, in my opinion, more readable.<br />
<br />
=== Encrypt System Partition ===<br />
<br />
Encrypt the main partition. Use a good passphrase. Note that the "--align-payload" value has been used as per [http://www.spinics.net/lists/dm-crypt/msg02421.html this suggestion/explanation] on the dm-crypt mailing list.<br />
<br />
Note also that I selected the encryption algorithm and key size using cryptsetup benchmark. See the [[Dm-crypt/Device_encryption]] article for more details.<br />
<br />
# cryptsetup luksFormat --align-payload=8192 -s 256 -c aes-xts-plain64 /dev/disk/by-partlabel/cryptsystem<br />
<br />
After creating the encrypted container, open it. Again, note the use of the partition label to identify the drive. Additionally, note that once we open this device we are giving it a name of "system." Thus "cryptsystem" is the encrypted system partition, while "system" is the name we are using once it has been opened in an unencrypted state. These names are arbitrary (Linux doesn't care what we use) but they help us keep things organized during this process.<br />
<br />
# cryptsetup open /dev/disk/by-partlabel/cryptsystem system<br />
<br />
=== Bring Up Encrypted Swap ===<br />
<br />
Finally we create encrypted swap. In this example we are not enabling hibernation. I will provide information on how to enable hibernation separately. Again, using partition labels to identify the partition and going from "cryptswap" to just "swap".<br />
<br />
We are not using LUKS here (which effectively makes dm-crypt easier to use). We're just using plain dm-crypt to encrypt the swap partition using a random key.<br />
<br />
# cryptsetup open --type plain --key-file /dev/urandom /dev/disk/by-partlabel/cryptswap swap<br />
# mkswap -L swap /dev/mapper/swap<br />
# swapon -L swap<br />
<br />
=== Create and mount BTRFS subvolumes ===<br />
<br />
Now on to the main attraction: creating our BTRFS subvolume structure. While BTRFS can be set up like any other filesystem (single command, just use the created file system directly), we're going to use the power of BTRFS to enable snapshotting our system state efficiently and rollbacks as necessary.<br />
<br />
First we create a top-level BTRFS subvolume. Note that the top-level entity in BTRFS nomenclature is still referred to as a '''sub'''volume, despite being at the top-level.<br />
<br />
We will create and mount this subvolume, create some new subvolumes inside it, and then switch to those subvolumes as our proper, mounted filesystems. Doing this will enable us to treat our root filesystem as a snapshotable object.<br />
<br />
Top-level subvolume creation.<br />
<br />
# mkfs.btrfs --force --label system /dev/mapper/system<br />
<br />
Temporarily mount our top-level volume for further subvolume creation. Note that the variable 'o' in this case is our default set of options for any given filesystem mount, while "o_btrfs" are those plus some options specific to btrfs. The default option "x-mount.mkdir" is a neat trick that allows us to skip the creation of directories for mountpoints (they will be created automatically). We assume /mnt as the standard mount point, as in a normal Arch Linux installation.<br />
<br />
# o=defaults,x-mount.mkdir<br />
# o_btrfs=$o,compress=lzo,ssd,noatime<br />
<br />
Note the use of our filesystem label to mount our subvolume. This is distinct from the partition labels used earlier. See the Arch wiki article on [[Persistent_block_device_naming]] for more information.<br />
<br />
# mount -t btrfs LABEL=system /mnt<br />
<br />
Now we create the subvolumes which will actually be mounted in our running system:<br />
<br />
# btrfs subvolume create /mnt/root<br />
# btrfs subvolume create /mnt/home<br />
# btrfs subvolume create /mnt/snapshots<br />
<br />
Then we unmount everything...<br />
<br />
# umount -R /mnt<br />
<br />
And remount just the subvolumes under our top-level subvolume (which remains unmounted unless we need to do "surgery" and rollback to a previous system system):<br />
<br />
# mount -t btrfs -o subvol=root,$o_btrfs LABEL=system /mnt<br />
<br />
Before mounting the home and snapshots subvolumes, let's walk through that command so we understand what it's doing:<br />
<br />
The 'mount -t btrfs' just specifies that our filesystem is of type BTRFS. This is often not necessary since mount will attempt to identify the filesystem type, but being explicit is often the best strategy with command line utilities, so we identify the type here.<br />
<br />
We use our previously defined mount options with the $o_btrfs variable and add the additional option "subvol=root" (separating it from our other defaults with a comma, of course). The next part of the command is "LABEL=system". Combined this reads as "mount the filesystem with the 'system' label, and use the 'root' subvolume within that".<br />
<br />
Finally, all this gets mounted at our install root, which in this case is "/mnt".<br />
<br />
Now let's pick back up and mount our home and snapshots subvolumes. Note that while the subvolume name is "snapshots", we will mount it at ".snapshots" (note dot prefix for the mount point). This will keep our root directory listing clean but will still make it available at a reasonable mount location.<br />
<br />
# mount -t btrfs -o subvol=home,$o_btrfs LABEL=system /mnt/home<br />
# mount -t btrfs -o subvol=snapshots,$o_btrfs LABEL=system /mnt/.snapshots<br />
<br />
It it worth noting that in each case we are telling mount to use the same filesystem, namely the one labeled "system". However in each case we are also telling it to look for a different subvolume in that filesystem (via the "subvol=" option).<br />
<br />
With this done, we can move on to installing the actual system.<br />
<br />
=== Mount EFI partition ===<br />
<br />
# mount LABEL=EFI /mnt/boot<br />
<br />
== Installation of Base Arch Linux System ==<br />
<br />
We are currently running off the Arch installer root filesystem. We will first use the 'pacstrap' utility to start our installation and then we will boot into our new minimal system using systemd-nspawn.<br />
<br />
=== Install base package group ===<br />
<br />
# pacstrap /mnt base<br />
<br />
=== fstab Generation and Modification ===<br />
<br />
{{Note|In a simpler, non encrypted configuration it is possible to skip making an fstab altogether due to a standard known as the [https://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/ Discoverable Partitions Spec]. However given the complexity of our encrypted, btrfs subvolume configuration, we require an fstab at this time. It is possible that in future we might feasibly do away with the fstab almost entirely in this setup (see the [https://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/#whataboutautomaticmountingofbtrfssubvolumestovarhomeandsoon 'What about automatic mounting of btrfs subvolumes'] section on that page).}}<br />
<br />
Create an [[fstab]] filesystem table file, using labels (-L) to identify the filesystems.<br />
<br />
# genfstab -L -p /mnt >> /mnt/etc/fstab<br />
<br />
I prefer to use labels as this makes the system more portable to a backup drive. You should end up with something that looks pretty close to this:<br />
<br />
{{hc|# cat /mnt/etc/fstab|<nowiki><br />
# /dev/mapper/system UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=system / btrfs rw,noatime,compress=lzo,ssd,space_cache,subvolid=257,subvol=/root,subvol=root 0 0<br />
<br />
# /dev/mapper/system UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=system /home btrfs rw,noatime,compress=lzo,ssd,space_cache,subvolid=258,subvol=/home,subvol=home 0 0<br />
<br />
# /dev/mapper/system UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=system /.snapshots btrfs rw,noatime,compress=lzo,ssd,space_cache,subvolid=259,subvol=/snapshots,subvol=snapshots 0 0<br />
<br />
# /dev/nvme0n1p1 UUID=xxxx-xxxx<br />
LABEL=EFI /boot/EFI vfat rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro 0 2<br />
<br />
# /dev/mapper/swap UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=swap none swap defaults 0 0<br />
</nowiki>}}<br />
<br />
There is one problem, however. Swap will not remount this way (the plain dm-crypt partition with a random key will not have a label when it is recreated on reboot). You will have to change that line from this:<br />
<br />
{{bc|<nowiki>LABEL=swap none swap defaults 0 0</nowiki>}}<br />
<br />
to this:<br />
<br />
{{bc|/dev/mapper/swap none swap defaults 0 0}}<br />
<br />
This will ensure that the mapped device is opened as swap successfully. The other lines may remain unchanged.<br />
<br />
==== Use {{ic|sed}} instead ====<br />
<br />
As a (scriptable) alternative to the manual editing of your {{ic|/etc/fstab}} you could use {{Man|1|sed}} to edit the file in place:<br />
<br />
# sed -i s+LABEL=swap+/dev/mapper/swap+ /mnt/etc/fstab_labels<br />
<br />
=== Boot into new system ===<br />
<br />
{{Warning|While this works, I am fairly certain I'll want to double check some things before declaring this step final. Specifically I want to consider some bind mounts and whether there is anything that should be r/w instead of r/o as is normal in a systemd-nspawn container.}}<br />
<br />
# systemd-nspawn -bD /mnt<br />
<br />
This will boot your new base Arch Linux system. After the standard boot messages scroll by you will be presented with a login (enter {{ic|root}} and hit enter to login).<br />
<br />
=== Generate and set locale ===<br />
<br />
Next, edit and uncomment your desired locale(s) from {{ic|/etc/locale.gen}}. We use {{ic|vi}} in the example below, but you could use a simpler editor such as {{ic|nano}} if you wish.<br />
<br />
{{hc|vi /etc/locale.gen|<nowiki><br />
...<br />
#en_PH.UTF-8 UTF-8<br />
#en_PH ISO-8859-1<br />
#en_SG.UTF-8 UTF-8<br />
#en_SG ISO-8859-1<br />
#en_US.UTF-8 UTF-8<br />
#en_US ISO-8859-1<br />
#en_ZA.UTF-8 UTF-8<br />
#en_ZA ISO-8859-1<br />
#en_ZM UTF-8<br />
...<br />
</nowiki>}}<br />
<br />
Changing it to (for en_US.UTF-8 as a locale in this example):<br />
<br />
{{bc|<nowiki><br />
...<br />
#en_PH.UTF-8 UTF-8<br />
#en_PH ISO-8859-1<br />
#en_SG.UTF-8 UTF-8<br />
#en_SG ISO-8859-1<br />
en_US.UTF-8 UTF-8<br />
#en_US ISO-8859-1<br />
#en_ZA.UTF-8 UTF-8<br />
#en_ZA ISO-8859-1<br />
#en_ZM UTF-8<br />
...<br />
</nowiki>}}<br />
<br />
Alternately one could simply append a known value to the {{ic|/etc/locale.gen}} file:<br />
<br />
# echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen<br />
<br />
After either method, one runs the {{ic|locale-gen}} command to generate the locale files:<br />
<br />
# locale-gen<br />
<br />
Finally we use {{Man|1|systemd-firstboot}} or {{Man|1|localectl}} to set the system locale. Each of these effectively does the same thing which is to simply write to {{ic|/etc/locale.conf}} (which can simply be edited directly as per standard Arch install instructions).<br />
<br />
==== With systemd-firstboot ====<br />
<br />
{{Man|1|systemd-firstboot}} will prompt us for selection from our generated locales. It will only work if there is no assigned system locale. If you wish to make changes afterward you can use {{Man|1|localectl}}<br />
<br />
# systemd-firstboot --prompt-locale<br />
<br />
==== With localectl ====<br />
<br />
This is an alternate to using {{ic|systemd-firstboot --prompt-locale}}. It may also be used subsequent to that command if further changes to the locale are desired.<br />
<br />
If you need a reminder of which locales have been installed (during this install or later during system changes), use {{ic|localectl list-locales}}:<br />
<br />
{{hc|<nowiki># localectl list-locales</nowiki>|en_US.UTF-8}}<br />
<br />
We then use {{ic|localectl set-locale}}:<br />
<br />
# localectl set-locale LANG=en_US.UTF-8<br />
<br />
=== Time and Date ===<br />
<br />
Unless you have a reason not to, we'll turn on NTP synchronization.<br />
<br />
# timedatectl set-ntp 1<br />
<br />
Then list timezones and pick one<br />
<br />
{{hc|<nowiki># timedatectl list-timezones</nowiki>|<nowiki><br />
...<br />
America/Kentucky/Louisville<br />
America/Kentucky/Monticello<br />
America/Kralendijk<br />
America/La_Paz<br />
America/Lima<br />
America/Los_Angeles<br />
America/Lower_Princes<br />
America/Maceio<br />
America/Managua<br />
America/Manaus<br />
America/Marigot<br />
America/Martinique<br />
America/Matamoros<br />
...<br />
</nowiki>}}<br />
# timedatectl set-timezone America/Los_Angeles<br />
<br />
=== Set hostname ===<br />
<br />
# hostnamectl set-hostname myhostname<br />
<br />
See the man page for {{Man|1|hostnamectl}} for other attributes that can be set. You might also add the hostname to {{Man|5|hosts}}:<br />
<br />
{{hc|/etc/hosts|<br />
127.0.0.1 localhost.localdomain localhost<br />
::1 localhost.localdomain localhost<br />
'''127.0.1.1 ''myhostname''.localdomain ''myhostname'''''<br />
}}<br />
<br />
Use {{ic|echo}} for a scriptable solution:<br />
<br />
# echo "127.0.1.1 myhostname.localdomain myhostname" >> /etc/hosts<br />
<br />
=== Network configuration ===<br />
<br />
Configure the network for the newly installed environment: see [[Network configuration]].<br />
<br />
For [[Wireless configuration]], [[Help:Reading#Installation of packages|install]] the {{Pkg|iw}}, {{Pkg|wpa_supplicant}}, and {{Pkg|dialog}} packages, as well as needed [[Wireless#Installing driver/firmware|firmware packages]].<br />
<br />
=== Base Package Installation ===<br />
<br />
We've already included the {{Grp|base}} group which is, strictly speaking, all you need to boot a minimal Arch Linux system. At this stage, however, we can install some useful utilities (and Xorg or Wayland, etc.).<br />
<br />
# pacman -Syu base-devel btrfs-progs iw gptfdisk zsh vim terminus-font<br />
<br />
=== Initramfs ===<br />
<br />
Creating a new ''initramfs'' is usually not required, because [[mkinitcpio]] was run on installation of the {{Pkg|linux}} package with ''pacstrap''. However we'll need to make some changes to the hooks used on our system. Additionally, I switched over to using the systemd hooks in mkinitcpio, so that is largely what you'll see in my example below.<br />
<br />
I recommend making a backup of your {{ic|/etc/mkinitcpio.conf}} file first:<br />
<br />
# mv /etc/mkinitcpio.conf /etc/mkinitcpio.conf.orig<br />
<br />
and then editing a new file to match the following contents:<br />
<br />
{{bc|<nowiki><br />
MODULES=""<br />
BINARIES=""<br />
FILES=""<br />
HOOKS="base systemd sd-vconsole modconf keyboard block filesystems btrfs sd-encrypt fsck"<br />
</nowiki>}}<br />
<br />
Finally, recreate the initramfs image:<br />
<br />
# mkinitcpio -p linux<br />
<br />
=== Bootloader ===<br />
<br />
{{Warning|THIS SECTION IN PROGRESS}}<br />
<br />
=== Root password ===<br />
<br />
Set the root [[password]]:<br />
<br />
# passwd<br />
<br />
=== Leave the systemd-nspawn environment ===<br />
<br />
Issue a poweroff to exit the nspawned environment:<br />
<br />
# poweroff<br />
<br />
This will return you the Arch installer environment where you can wrap up.<br />
<br />
=== Legacy boot loader ===<br />
<br />
If your system is not UEFI and you need to use a legacy installer like grub, it will need to be installed from within an arch-chroot generated chroot, not the systemd-nspawn running container. An example of this would be (assuming that the drive of the new system is at /dev/sdb):<br />
<br />
# arch-chroot /mnt<br />
# grub-install $DRIVE<br />
# grub-mkconfig -o /boot/grub/grub.cfg<br />
# exit<br />
<br />
== Command Summary ==<br />
<br />
The following are all critical commands (exluded: the initial drive wipe which is optional). It assumes you have successfully brought up networking prior to starting this sequence.<br />
<br />
{{bc|<nowiki><br />
<br />
DRIVE=/dev/DRIVEID<br />
<br />
sgdisk --zap-all $DRIVE<br />
<br />
sgdisk --clear \<br />
--new=1:0:+550MiB --typecode=1:ef00 --change-name=1:EFI \<br />
--new=2:0:+8GiB --typecode=2:8200 --change-name=2:cryptswap \<br />
--new=3:0:0 --typecode=2:8200 --change-name=3:cryptsystem \<br />
$DRIVE<br />
<br />
mkfs.fat -F32 -n EFI /dev/disk/by-partlabel/EFI<br />
<br />
cryptsetup luksFormat --align-payload=8192 -s 256 -c aes-xts-plain64 /dev/disk/by-partlabel/cryptsystem<br />
<br />
cryptsetup open /dev/disk/by-partlabel/cryptsystem system<br />
<br />
cryptsetup open --type plain --key-file /dev/urandom /dev/disk/by-partlabel/cryptswap swap<br />
<br />
mkswap -L swap /dev/mapper/swap<br />
<br />
swapon -L swap<br />
<br />
mkfs.btrfs --force --label system /dev/mapper/system<br />
<br />
o=defaults,x-mount.mkdir<br />
<br />
o_btrfs=$o,compress=lzo,ssd,noatime<br />
<br />
mount -t btrfs LABEL=system /mnt<br />
<br />
btrfs subvolume create /mnt/root<br />
<br />
btrfs subvolume create /mnt/home<br />
<br />
btrfs subvolume create /mnt/snapshots<br />
<br />
umount -R /mnt<br />
<br />
mount -t btrfs -o subvol=root,$o_btrfs LABEL=system /mnt<br />
<br />
mount -t btrfs -o subvol=home,$o_btrfs LABEL=system /mnt/home<br />
<br />
mount -t btrfs -o subvol=snapshots,$o_btrfs LABEL=system /mnt/.snapshots<br />
<br />
pacstrap /mnt base<br />
<br />
genfstab -L -p /mnt >> /mnt/etc/fstab<br />
<br />
sed -i "s+LABEL=swap+/dev/mapper/swap" /etc/fstab_labels<br />
<br />
systemd-nspawn -bD /mnt<br />
<br />
echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen<br />
<br />
locale-gen<br />
<br />
localectl set-locale LANG=en_US.UTF-8<br />
<br />
timedatectl set-ntp 1<br />
<br />
timedatectl set-timezone America/Los_Angeles<br />
<br />
hostnamectl set-hostname myhostname<br />
<br />
echo "127.0.1.1 myhostname.localdomain myhostname" >> /etc/hosts<br />
<br />
pacman -Syu base-devel btrfs-progs iw gptfdisk zsh vim terminus-font<br />
</nowiki>}}<br />
<br />
== Quick and Dirty ==<br />
<br />
{{Note|an extra example and may be moved to its own wiki page later}}<br />
<br />
This is the approximate process I follow if I want to bring up Arch on, say, an old laptop for a quick purpose built test machine, etc. It's not an install that I consider long term maintainable since rollbacks aren't implemented, nor is there any encryption, but it's a good example of how simple installation can be.<br />
<br />
{{bc|<nowiki><br />
DRIVE=/dev/DRIVEID<br />
sgdisk --zap-all $DRIVE<br />
mkfs.btrfs -f $DRIVE<br />
mount -t btrfs $DRIVE /mnt<br />
pacstrap /mnt base grub<br />
systemd-nspawn -bD /mnt<br />
echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen<br />
locale-gen<br />
localectl set-locale LANG=en_US.UTF-8<br />
timedatectl set-ntp 1<br />
timedatectl set-timezone America/Los_Angeles<br />
hostnamectl set-hostname myhostname<br />
poweroff<br />
arch-chroot /mnt<br />
grub-install --root-directory=/mnt $DRIVE<br />
grub-mkconfig -o /mnt/boot/grub/grub.cfg<br />
exit<br />
reboot<br />
</nowiki>}}</div>Altercationhttps://wiki.archlinux.org/index.php?title=User:Altercation/Bullet_Proof_Arch_Install&diff=458972User:Altercation/Bullet Proof Arch Install2016-12-10T17:41:40Z<p>Altercation: /* Command Summary */</p>
<hr />
<div>This page is a summary of the current process I follow when installing Arch on a new laptop or desktop. My process varies over time, but this serves as my "state of the art" best practice recommendations. I'm open to feedback and suggestions for improvements.<br />
<br />
{{Note|This is entirely based on my own opinions and research. It is opinionated about the best way to do things given the current state of the kernel, hardware availability, and utilities, filesystems, etc. I will explain my rationale for specific choices and provide links to other sources of information (on the Arch wiki or external) where useful.}}<br />
<br />
== Objectives ==<br />
<br />
The goals of my standard "bullet proof" Arch Linux installation are:<br />
<br />
* Benefit from Arch's rolling release model while mitigating any risk of system corruption or data loss due to failed upgrades<br />
* Minimize risk due to hardware failure or total system loss (e.g. theft or physical destruction)<br />
* Make system rollbacks easy and procedural, using a standard setup and methodology for recovery of previous system (and user data) states<br />
<br />
=== Why not the Arch Install instructions? ===<br />
<br />
The [[Installation guide|Arch Linux installation instructions]] are an excellent, general starting point and you should read and understand them. That being said, they are designed to map to a very, very broad set of installation scenarios. I am interested in a very specific type of installation (daily use desktops and laptops in this article) and I have a strong set of opinions about the "right" or "best practice" way to set up my own working systems.<br />
<br />
These instructions, then, are much more prescriptive and have strong suggestions or directions about how (and why) one should use a particular method during Arch Linux installation.<br />
<br />
=== Key differences from the stock Arch install instructions ===<br />
<br />
How these instructions differ from the standard Arch guidance:<br />
<br />
* We are encrypting the entire system but not using LVM as is often recommended (see the encryption section below for details about why we are not using it).<br />
* I use labels and avoid UUIDs where possible to make switching to an alternate recovery drive easier.<br />
* I skip arch-chroot and simply boot the new system ('''not''' reboot, just boot) from within the install environment using {{Man|1|systemd-nspawn}} which enables the *ctl commands to work (and systemd services to be enabled properly without need for a system reboot)<br />
* I use the various systemd *ctl commands (hostnamectl, timedatectl, localectl, etc.) to configure the system<br />
* I use the systemd mkinitcpio hooks in lieu of the legacy hooks.<br />
* I use BTRFS exclusively for root and home partitions for its backup capabilities.<br />
* I recommend and use secure boot (but not with the Microsoft keys) to minimize risk due to the unavoidably unencrypted EFI partition.<br />
<br />
== Assumptions ==<br />
<br />
These instructions presuppose the following:<br />
<br />
* fairly new hardware (these instructions may work on older hardware, but there may be unusual issues that crop up... if you aren't comfortable handling those situations you should consider a more "traditional" Arch Linux install (e.g. using grub, LVM, ext4, etc.)<br />
* [[Unified Extensible Firmware Interface|UEFI support]] (BIOS system install is also possible with some modification of these instructions, but this has not yet been detailed here)<br />
* probably an [[Solid State Drives|SSD]].<br />
* some familiarity with Arch, or at least some experience with Linux, will help<br />
<br />
{{Warning|I am assuming you are going to single boot (not dual boot) and that you are '''willing to wipe all data from the install drive.''' If that is not the case, do not proceed with these instructions as following them '''will effectively destroy any data (and other operating systems) on the installation target drive.'''}}<br />
<br />
== Prerequisites ==<br />
<br />
You must have a recent copy of the Arch install USB. See [[:Category:Getting and installing Arch]] for general information and [[USB flash installation media]] for specific details on creating a USB Arch installation drive.<br />
<br />
You should also have a reasonable amount of time in which to complete the installation. Novice users will want to budget a couple hours. Experienced users will ''know'' to budget a couple hours.<br />
<br />
== Preparation ==<br />
<br />
=== Boot from USB Drive ===<br />
<br />
Boot your system from your prepared [[USB flash installation media|Arch Linux USB drive]]. It is important that you boot in EFI mode, not legacy BIOS compatibility mode. See the [[Unified Extensible Firmware Interface|UEFI]] article for more information about checking boot mode and ensuring you are booting using EFI.<br />
<br />
=== Bring up the network ===<br />
<br />
If you booted into a system with an ethernet cable plugged in, chances are you're up and running. If you need to use wireless instead, {{ic|wifi-menu}} will more often than not work without trouble. If those don't work, see [[Installation guide#Connect to the Internet|the Arch installation guide section on connecting to the internet]].<br />
<br />
=== Select Drive ===<br />
<br />
I like to use the [[Core utilities#lsblk|{{ic|1=lsblk}}]] command to bring up a quick list of the block devices on the system and identify existing partition structures and sizes, as well as mount points. If you don't already use it, I recommend [[Core utilities#lsblk|{{ic|1=lsblk}}]] when you need information on any given drive or partition. It's useful for polling UUIDs as well. For example, the following command gives you a clearly formatted summary of all block devices, their partition labels, filesystem lables, UUIDs and partition UUIDS: {{ic|lsblk -o +LABEL,PARTLABEL,UUID,PARTUUID}}<br />
<br />
In any case, the plain command without options should be enough to identify the drive you will install to (for example {{ic|1=/dev/sda}} or {{ic|1=/dev/nvme0n1}}:<br />
<br />
# lsblk<br />
<br />
=== Wipe Drive Securely (optional) ===<br />
<br />
While it is not necessary, given that this process will go through the trouble of encrypting the main system partition, it makes sense to do a secure wipe of the drive. This is more or less directly from [[Dm-crypt/Drive preparation#dm-crypt wipe on an empty disk or partition]].<br />
<br />
{{Warning|Be certain of your target device selection as we will be '''wiping this drive''' (either securely or, at minimum, destroying all existing partition data).}}<br />
<br />
First, create a temporary encrypted container the full disk ({{ic|sdX}}) to be encrypted, e.g. using default encryption parameters and a random key via the {{ic|--key-file /dev/{u}random}} option (see also [[Random number generation]]):<br />
<br />
# cryptsetup open --type plain /dev/sdXY container --key-file /dev/urandom<br />
<br />
{{Note|An interesting page addressing myths about /dev/urandom can be [http://www.2uo.de/myths-about-urandom/ found here]}}<br />
<br />
Second, check the container exists:<br />
<br />
{{hc|# fdisk -l|Disk /dev/mapper/container: XXXX MB, XXXXXXXXXX bytes<br />
...<br />
Disk /dev/mapper/container does not contain a valid partition table}}<br />
Wipe the container with zeros. A use of {{ic|1=if=/dev/urandom}} is '''not''' required as the encryption cipher itself generates randomness.<br />
{{hc|# dd <nowiki>if=/dev/zero of=/dev/mapper/container status=progress bs=1M</nowiki>|<br />
dd: writing to ‘/dev/mapper/container’: No space left on device}}<br />
<br />
{{Tip|<br />
* Using ''dd'' with the {{ic|1=bs=}} option, e.g. {{ic|1=bs=1M}} as above, is frequently used to increase disk throughput of the operation.<br />
* To perform a check of the operation, zero the partition before creating the wipe container. After the wipe command {{ic|blockdev --getsize64 ''/dev/mapper/container''}} can be used to get the exact container size as root. Now ''od'' can be used to spotcheck whether the wipe overwrote the zeroed sectors, e.g. {{ic|od -j ''containersize - blocksize''}} to view the wipe completed to the end.}}<br />
<br />
Finally, close the temporary container:<br />
<br />
# cryptsetup close container<br />
<br />
== Partition & Format Drive ==<br />
<br />
=== Understanding some basics about disks, partitions, and filesystems ===<br />
<br />
Think of your drive like a big empty building, no rooms. This is your plain physical drive (either a spinning platter drive or an SSD). Next imagine that to make it useful, we divide the building into apartments. In our analogy the apartments are '''partitions''' of the drive.<br />
<br />
Imagine also that there are a couple different standard methods of creating layout maps to the apartments. These plans are standardized so that the public services that have to access the building regularly (like the fire and police, for example) understand how to find the apartment entrances. In the world of partitioning, the equivalent is the "partition table scheme". The two common schemes are called "MBR" (Master Boot Record, older) and "GPT" (GUID Partition Table, newer). We will be using the new GPT scheme.<br />
<br />
Finally, imagine that the apartments are just empty shells. The act of building walls and laying out the functional structure of the apartments is equivalent to formatting our disk partitions with a filesystem. And just as different layouts may be more or less efficient, or have other different functional characteristics, so to filesystems have different attributes that make them useful in different ways.<br />
<br />
=== Our partition plans ===<br />
<br />
We will take our physical drive and divide it into three partitions. These partitions each serve a distinct purpose. All but the first and smallest, the EFI partition, will be encrypted. For security, if your system supports Secure Boot, you may choose to cryptographically sign the data stored on the EFI partition so that any tampering will be evident, despite the lack of encryption on that partition.<br />
<br />
{{Note|Again, we're assuming an UEFI installation (not legacy BIOS) and a GPT (not MBR) partition structure. If none of that made sense, best to start with the [[Partitioning]] article or do some test installs of Arch first. '''Partitioning is, in my opinion, one of the areas that is most confusing for the new Arch user.''' Additionally, there is a lot "received wisdom" and cargo-cult assumption making about how best to partition. Working through some of the "this is how it's always been done" tutorials isn't necessarily a bad thing... In many cases the way it has always been done has some sound reasoning behind it, despite being cargo-culted half the time. That being said, the method presented here is different from that in most of the Arch wiki partitioning methodologies.}}<br />
<br />
We will not be using LVM. You read a lot about LUKS and LVM and it all gets a bit complicated (LVM on LUKS, LUKS on LVM, etc.). LVM is a "logical volume manager" and abstracts physical devices (drives) into virtual devices, for easier management. It's a good idea but we will be using btrfs to effectively achieve the same results and really don't need the overhead of LVM.<br />
<br />
=== Partition Summary ===<br />
<br />
* 1: EFI - The UEFI 'bios" will look for this FAT32 formatted partition and either locate a default bootloader or will locate a specific EFI boot entry on it. This partition is by necessity not encrypted (unless the drive it is on has been encrypted as a "self encrypting drive")<br />
* 2: Swap - Used by Linux to swap out pages of memory from RAM to disk. Despite debate in this area, it is advisable to have at least some swap space, even it you are not planning on using hibernation on your machine. The Arch wiki is unfortunately rather too brief in its own [[Swap|swap article]] so I recommend the [https://docs.fedoraproject.org/en-US/Fedora/14/html/Storage_Administration_Guide/ch-swapspace.html Fedora documentation on swap] for a good overview on determining the right swap partition size.<br />
* 3: System - This will hold our root and home data. It will be formatted as BTRFS and will use subvolumes to manage snapshots of the current root and home contents.<br />
<br />
=== Visual overview of our partitions, filesystems, and contents ===<br />
<br />
This is a visual summary of our partions (inc. size information), encryption, filesystems, and a summary of the contents of each container.<br />
<br />
{| class="wikitable"<br />
| style="vertical-align: top; padding:1em" | '''Partition 1 (EFI)'''<br />
550MiB+<br />
{| style="border: 1px solid black; background: #DACEF2; margin: 1em;"<br />
! FAT32<br />
|-<br />
|kernel & initramfs<br />
(signed if using secure boot)<br />
|}<br />
| style="vertical-align: top; padding:1em" | '''Partition 2 (Swap)'''<br />
w/ Hibernate: Equal RAM,<br />
w/o Hibernate: min 8GB<br />
{| style="border: 1px solid black; background: #F2ECCE; margin: 1em;"<br />
|-<br />
! dm-crypt<br />
{| style="border: 1px solid black; background: #DACEF2; margin: 1em;"<br />
| SWAP<br />
|}<br />
|}<br />
| style="vertical-align: top; padding:1em" | '''Partition 3 (System)'''<br />
Remaining Space<br />
{| style="border: 1px solid black; background: #F2ECCE; margin: 1em;"<br />
|-<br />
! LUKS dm-crypt<br />
<br />
{| style="border: 1px solid black; background: #DACEF2; margin: 1em;"<br />
| BTRFS Top Level Subvolume<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Root Subvolume<br />
|}<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Home Subvolume<br />
|}<br />
<br />
{| style="border: 1px solid black; background: #E0CEF2; margin: 1em;"<br />
| BTRFS Snapshots Subvolume<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Root Snapshot Subvolume(s)<br />
|}<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Home Snapshot Subvolume(s)<br />
|}<br />
<br />
|}<br />
<br />
|}<br />
<br />
|}<br />
<br />
|}<br />
<br />
=== Partition Drive ===<br />
<br />
There are many utilities available for [[Partitioning]]. Because we are using Arch Linux and the command line doesn't hurt us (it makes us stronger) we will be using pure, non-interactive command line tools for this. Specifically, we will be using the utility [[Fdisk#Using_sgdisk|sgdisk]] from the {{Pkg|gptfdisk}} package. The [[Fdisk|fdisk]] utility now also supports GPT partitioned drives, so it would be an alternative. [[Fdisk#Using_sgdisk|sgdisk]] is available by default on the standard Arch install iso that you use to make your bootable USB drive.<br />
<br />
First, select the drive you will install to. Make sure you have selected the correct drive!. Again, a quick {{ic|lsblk}} will work here.<br />
<br />
# $DRIVE=/dev/DRIVEID<br />
<br />
(replace /dev/DRIVEID with the correct value, for example /dev/sda, /dev/nvme0n1, etc.)<br />
<br />
If you didn't securely wipe the drive already, it's worth "zapping" it using [[Fdisk#Using_sgdisk|sgdisk]] to remove any lingering legacy partition information. If you already wiped the drive you can skip this command (though it won't hurt to run it again).<br />
<br />
{{Warning|'''This command will also effectively erase the selected drive!'''}}<br />
<br />
# sgdisk --zap-all $DRIVE<br />
<br />
The following command will then create all three partitions in one go. '''It will also effectively erase the selected drive!'''<br />
<br />
# sgdisk --clear \<br />
--new=1:0:+550MiB --typecode=1:ef00 --change-name=1:EFI \<br />
--new=2:0:+8GiB --typecode=2:8200 --change-name=2:cryptswap \<br />
--new=3:0:0 --typecode=2:8200 --change-name=3:cryptsystem \<br />
$DRIVE<br />
<br />
It is worth noting that the "--change-name" values are, in this case, creating GPT "partition labels". You can subsequently see these by using the {{ic|lsblk -o +PARTLABEL}} command. It is good to use "EFI" for the efi partition. I am not aware of UEFI implementations that actively use the label for identification of the EFI partition, but it is possible that some do (UEFI bios implementations are not always consistent or to spec). The other two names are entirely "arbitrary". There is nothing special about calling them cryptswap and cryptsystem; they are simply good, clear names that remind us of the purpose of this partition and what it contains (for example, "cryptswap" suggests "this partition is for swap, and is encrypted").<br />
<br />
One final note about partition labels: we want them to be unique on your system. If for some reason there is already a GPT partition with the name EFI on another drive on your system, either change that partition name or use something besides "EFI" to avoid a namespace collision.<br />
<br />
Note also, that the backslashes at the end of each line can be omitted if you are writing the command on one long line instead. Those simply allow the splitting of a single command onto multiple lines.<br />
<br />
=== Format EFI Partition ===<br />
<br />
Next up: format the first (EFI) partition using the (required) FAT32 filesystem.<br />
<br />
# mkfs.fat -F32 -n EFI /dev/disk/by-partlabel/EFI<br />
<br />
Note that we here make use of the partition label we just assigned. I prefer doing this since it simplifies scripts significantly for me and makes them, in my opinion, more readable.<br />
<br />
=== Encrypt System Partition ===<br />
<br />
Encrypt the main partition. Use a good passphrase. Note that the "--align-payload" value has been used as per [http://www.spinics.net/lists/dm-crypt/msg02421.html this suggestion/explanation] on the dm-crypt mailing list.<br />
<br />
Note also that I selected the encryption algorithm and key size using cryptsetup benchmark. See the [[Dm-crypt/Device_encryption]] article for more details.<br />
<br />
# cryptsetup luksFormat --align-payload=8192 -s 256 -c aes-xts-plain64 /dev/disk/by-partlabel/cryptsystem<br />
<br />
After creating the encrypted container, open it. Again, note the use of the partition label to identify the drive. Additionally, note that once we open this device we are giving it a name of "system." Thus "cryptsystem" is the encrypted system partition, while "system" is the name we are using once it has been opened in an unencrypted state. These names are arbitrary (Linux doesn't care what we use) but they help us keep things organized during this process.<br />
<br />
# cryptsetup open /dev/disk/by-partlabel/cryptsystem system<br />
<br />
=== Bring Up Encrypted Swap ===<br />
<br />
Finally we create encrypted swap. In this example we are not enabling hibernation. I will provide information on how to enable hibernation separately. Again, using partition labels to identify the partition and going from "cryptswap" to just "swap".<br />
<br />
We are not using LUKS here (which effectively makes dm-crypt easier to use). We're just using plain dm-crypt to encrypt the swap partition using a random key.<br />
<br />
# cryptsetup open --type plain --key-file /dev/urandom /dev/disk/by-partlabel/cryptswap swap<br />
# mkswap -L swap /dev/mapper/swap<br />
# swapon -L swap<br />
<br />
=== Create and mount BTRFS subvolumes ===<br />
<br />
Now on to the main attraction: creating our BTRFS subvolume structure. While BTRFS can be set up like any other filesystem (single command, just use the created file system directly), we're going to use the power of BTRFS to enable snapshotting our system state efficiently and rollbacks as necessary.<br />
<br />
First we create a top-level BTRFS subvolume. Note that the top-level entity in BTRFS nomenclature is still referred to as a '''sub'''volume, despite being at the top-level.<br />
<br />
We will create and mount this subvolume, create some new subvolumes inside it, and then switch to those subvolumes as our proper, mounted filesystems. Doing this will enable us to treat our root filesystem as a snapshotable object.<br />
<br />
Top-level subvolume creation.<br />
<br />
# mkfs.btrfs --force --label system /dev/mapper/system<br />
<br />
Temporarily mount our top-level volume for further subvolume creation. Note that the variable 'o' in this case is our default set of options for any given filesystem mount, while "o_btrfs" are those plus some options specific to btrfs. The default option "x-mount.mkdir" is a neat trick that allows us to skip the creation of directories for mountpoints (they will be created automatically). We assume /mnt as the standard mount point, as in a normal Arch Linux installation.<br />
<br />
# o=defaults,x-mount.mkdir<br />
# o_btrfs=$o,compress=lzo,ssd,noatime<br />
<br />
Note the use of our filesystem label to mount our subvolume. This is distinct from the partition labels used earlier. See the Arch wiki article on [[Persistent_block_device_naming]] for more information.<br />
<br />
# mount -t btrfs LABEL=system /mnt<br />
<br />
Now we create the subvolumes which will actually be mounted in our running system:<br />
<br />
# btrfs subvolume create /mnt/root<br />
# btrfs subvolume create /mnt/home<br />
# btrfs subvolume create /mnt/snapshots<br />
<br />
Then we unmount everything...<br />
<br />
# umount -R /mnt<br />
<br />
And remount just the subvolumes under our top-level subvolume (which remains unmounted unless we need to do "surgery" and rollback to a previous system system):<br />
<br />
# mount -t btrfs -o subvol=root,$o_btrfs LABEL=system /mnt<br />
<br />
Before mounting the home and snapshots subvolumes, let's walk through that command so we understand what it's doing:<br />
<br />
The 'mount -t btrfs' just specifies that our filesystem is of type BTRFS. This is often not necessary since mount will attempt to identify the filesystem type, but being explicit is often the best strategy with command line utilities, so we identify the type here.<br />
<br />
We use our previously defined mount options with the $o_btrfs variable and add the additional option "subvol=root" (separating it from our other defaults with a comma, of course). The next part of the command is "LABEL=system". Combined this reads as "mount the filesystem with the 'system' label, and use the 'root' subvolume within that".<br />
<br />
Finally, all this gets mounted at our install root, which in this case is "/mnt".<br />
<br />
Now let's pick back up and mount our home and snapshots subvolumes. Note that while the subvolume name is "snapshots", we will mount it at ".snapshots" (note dot prefix for the mount point). This will keep our root directory listing clean but will still make it available at a reasonable mount location.<br />
<br />
# mount -t btrfs -o subvol=home,$o_btrfs LABEL=system /mnt/home<br />
# mount -t btrfs -o subvol=snapshots,$o_btrfs LABEL=system /mnt/.snapshots<br />
<br />
It it worth noting that in each case we are telling mount to use the same filesystem, namely the one labeled "system". However in each case we are also telling it to look for a different subvolume in that filesystem (via the "subvol=" option).<br />
<br />
With this done, we can move on to installing the actual system.<br />
<br />
=== Mount EFI partition ===<br />
<br />
# mount LABEL=EFI /mnt/boot<br />
<br />
== Installation of Base Arch Linux System ==<br />
<br />
We are currently running off the Arch installer root filesystem. We will first use the 'pacstrap' utility to start our installation and then we will boot into our new minimal system using systemd-nspawn.<br />
<br />
=== Install base package group ===<br />
<br />
# pacstrap /mnt base<br />
<br />
=== fstab Generation and Modification ===<br />
<br />
{{Note|In a simpler, non encrypted configuration it is possible to skip making an fstab altogether due to a standard known as the [https://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/ Discoverable Partitions Spec]. However given the complexity of our encrypted, btrfs subvolume configuration, we require an fstab at this time. It is possible that in future we might feasibly do away with the fstab almost entirely in this setup (see the [https://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/#whataboutautomaticmountingofbtrfssubvolumestovarhomeandsoon 'What about automatic mounting of btrfs subvolumes'] section on that page).}}<br />
<br />
Create an [[fstab]] filesystem table file, using labels (-L) to identify the filesystems.<br />
<br />
# genfstab -L -p /mnt >> /mnt/etc/fstab<br />
<br />
I prefer to use labels as this makes the system more portable to a backup drive. You should end up with something that looks pretty close to this:<br />
<br />
{{hc|# cat /mnt/etc/fstab|<nowiki><br />
# /dev/mapper/system UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=system / btrfs rw,noatime,compress=lzo,ssd,space_cache,subvolid=257,subvol=/root,subvol=root 0 0<br />
<br />
# /dev/mapper/system UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=system /home btrfs rw,noatime,compress=lzo,ssd,space_cache,subvolid=258,subvol=/home,subvol=home 0 0<br />
<br />
# /dev/mapper/system UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=system /.snapshots btrfs rw,noatime,compress=lzo,ssd,space_cache,subvolid=259,subvol=/snapshots,subvol=snapshots 0 0<br />
<br />
# /dev/nvme0n1p1 UUID=xxxx-xxxx<br />
LABEL=EFI /boot/EFI vfat rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro 0 2<br />
<br />
# /dev/mapper/swap UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=swap none swap defaults 0 0<br />
</nowiki>}}<br />
<br />
There is one problem, however. Swap will not remount this way (the plain dm-crypt partition with a random key will not have a label when it is recreated on reboot). You will have to change that line from this:<br />
<br />
{{bc|<nowiki>LABEL=swap none swap defaults 0 0</nowiki>}}<br />
<br />
to this:<br />
<br />
{{bc|/dev/mapper/swap none swap defaults 0 0}}<br />
<br />
This will ensure that the mapped device is opened as swap successfully. The other lines may remain unchanged.<br />
<br />
==== Use {{ic|sed}} instead ====<br />
<br />
As a (scriptable) alternative to the manual editing of your {{ic|/etc/fstab}} you could use {{Man|1|sed}} to edit the file in place:<br />
<br />
# sed -i s+LABEL=swap+/dev/mapper/swap+ /mnt/etc/fstab_labels<br />
<br />
=== Boot into new system ===<br />
<br />
{{Warning|While this works, I am fairly certain I'll want to double check some things before declaring this step final. Specifically I want to consider some bind mounts and whether there is anything that should be r/w instead of r/o as is normal in a systemd-nspawn container.}}<br />
<br />
# systemd-nspawn -bD /mnt<br />
<br />
This will boot your new base Arch Linux system. After the standard boot messages scroll by you will be presented with a login (enter {{ic|root}} and hit enter to login).<br />
<br />
=== Generate and set locale ===<br />
<br />
Next, edit and uncomment your desired locale(s) from {{ic|/etc/locale.gen}}. We use {{ic|vi}} in the example below, but you could use a simpler editor such as {{ic|nano}} if you wish.<br />
<br />
{{hc|vi /etc/locale.gen|<nowiki><br />
...<br />
#en_PH.UTF-8 UTF-8<br />
#en_PH ISO-8859-1<br />
#en_SG.UTF-8 UTF-8<br />
#en_SG ISO-8859-1<br />
#en_US.UTF-8 UTF-8<br />
#en_US ISO-8859-1<br />
#en_ZA.UTF-8 UTF-8<br />
#en_ZA ISO-8859-1<br />
#en_ZM UTF-8<br />
...<br />
</nowiki>}}<br />
<br />
Changing it to (for en_US.UTF-8 as a locale in this example):<br />
<br />
{{bc|<nowiki><br />
...<br />
#en_PH.UTF-8 UTF-8<br />
#en_PH ISO-8859-1<br />
#en_SG.UTF-8 UTF-8<br />
#en_SG ISO-8859-1<br />
en_US.UTF-8 UTF-8<br />
#en_US ISO-8859-1<br />
#en_ZA.UTF-8 UTF-8<br />
#en_ZA ISO-8859-1<br />
#en_ZM UTF-8<br />
...<br />
</nowiki>}}<br />
<br />
Alternately one could simply append a known value to the {{ic|/etc/locale.gen}} file:<br />
<br />
# echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen<br />
<br />
After either method, one runs the {{ic|locale-gen}} command to generate the locale files:<br />
<br />
# locale-gen<br />
<br />
Finally we use {{Man|1|systemd-firstboot}} or {{Man|1|localectl}} to set the system locale. Each of these effectively does the same thing which is to simply write to {{ic|/etc/locale.conf}} (which can simply be edited directly as per standard Arch install instructions).<br />
<br />
==== With systemd-firstboot ====<br />
<br />
{{Man|1|systemd-firstboot}} will prompt us for selection from our generated locales. It will only work if there is no assigned system locale. If you wish to make changes afterward you can use {{Man|1|localectl}}<br />
<br />
# systemd-firstboot --prompt-locale<br />
<br />
==== With localectl ====<br />
<br />
This is an alternate to using {{ic|systemd-firstboot --prompt-locale}}. It may also be used subsequent to that command if further changes to the locale are desired.<br />
<br />
If you need a reminder of which locales have been installed (during this install or later during system changes), use {{ic|localectl list-locales}}:<br />
<br />
{{hc|<nowiki># localectl list-locales</nowiki>|en_US.UTF-8}}<br />
<br />
We then use {{ic|localectl set-locale}}:<br />
<br />
# localectl set-locale LANG=en_US.UTF-8<br />
<br />
=== Time and Date ===<br />
<br />
Unless you have a reason not to, we'll turn on NTP synchronization.<br />
<br />
# timedatectl set-ntp 1<br />
<br />
Then list timezones and pick one<br />
<br />
{{hc|<nowiki># timedatectl list-timezones</nowiki>|<nowiki><br />
...<br />
America/Kentucky/Louisville<br />
America/Kentucky/Monticello<br />
America/Kralendijk<br />
America/La_Paz<br />
America/Lima<br />
America/Los_Angeles<br />
America/Lower_Princes<br />
America/Maceio<br />
America/Managua<br />
America/Manaus<br />
America/Marigot<br />
America/Martinique<br />
America/Matamoros<br />
...<br />
</nowiki>}}<br />
# timedatectl set-timezone America/Los_Angeles<br />
<br />
=== Set hostname ===<br />
<br />
# hostnamectl set-hostname myhostname<br />
<br />
See the man page for {{Man|1|hostnamectl}} for other attributes that can be set. You might also add the hostname to {{Man|5|hosts}}:<br />
<br />
{{hc|/etc/hosts|<br />
127.0.0.1 localhost.localdomain localhost<br />
::1 localhost.localdomain localhost<br />
'''127.0.1.1 ''myhostname''.localdomain ''myhostname'''''<br />
}}<br />
<br />
Use {{ic|echo}} for a scriptable solution:<br />
<br />
# echo "127.0.1.1 myhostname.localdomain myhostname" >> /etc/hosts<br />
<br />
=== Network configuration ===<br />
<br />
Configure the network for the newly installed environment: see [[Network configuration]].<br />
<br />
For [[Wireless configuration]], [[Help:Reading#Installation of packages|install]] the {{Pkg|iw}}, {{Pkg|wpa_supplicant}}, and {{Pkg|dialog}} packages, as well as needed [[Wireless#Installing driver/firmware|firmware packages]].<br />
<br />
=== Base Package Installation ===<br />
<br />
We've already included the {{Grp|base}} group which is, strictly speaking, all you need to boot a minimal Arch Linux system. At this stage, however, we can install some useful utilities (and Xorg or Wayland, etc.).<br />
<br />
# pacman -Syu base-devel btrfs-progs iw gptfdisk zsh vim terminus-font<br />
<br />
=== Initramfs ===<br />
<br />
Creating a new ''initramfs'' is usually not required, because [[mkinitcpio]] was run on installation of the {{Pkg|linux}} package with ''pacstrap''. However we'll need to make some changes to the hooks used on our system. Additionally, I switched over to using the systemd hooks in mkinitcpio, so that is largely what you'll see in my example below.<br />
<br />
I recommend making a backup of your {{ic|/etc/mkinitcpio.conf}} file first:<br />
<br />
# mv /etc/mkinitcpio.conf /etc/mkinitcpio.conf.orig<br />
<br />
and then editing a new file to match the following contents:<br />
<br />
{{bc|<nowiki><br />
MODULES=""<br />
BINARIES=""<br />
FILES=""<br />
HOOKS="base systemd sd-vconsole modconf keyboard block filesystems btrfs sd-encrypt fsck"<br />
</nowiki>}}<br />
<br />
Finally, recreate the initramfs image:<br />
<br />
# mkinitcpio -p linux<br />
<br />
=== Bootloader ===<br />
<br />
{{Warning|THIS SECTION IN PROGRESS}}<br />
<br />
=== Root password ===<br />
<br />
Set the root [[password]]:<br />
<br />
# passwd<br />
<br />
=== Leave the systemd-nspawn environment ===<br />
<br />
Issue a poweroff to exit the nspawned environment:<br />
<br />
# poweroff<br />
<br />
This will return you the Arch installer environment where you can wrap up.<br />
<br />
=== Legacy boot loader ===<br />
<br />
If your system is not UEFI and you need to use a legacy installer like grub, it will need to be installed from within an arch-chroot generated chroot, not the systemd-nspawn running container. An example of this would be (assuming that the drive of the new system is at /dev/sdb):<br />
<br />
# arch-chroot /mnt<br />
# grub-install $DRIVE<br />
# grub-mkconfig -o /boot/grub/grub.cfg<br />
# exit<br />
<br />
== Command Summary ==<br />
<br />
The following are all critical commands (exluded: the initial drive wipe which is optional). It assumes you have successfully brought up networking prior to starting this sequence.<br />
<br />
{{bc|<nowiki><br />
<br />
DRIVE=/dev/DRIVEID<br />
<br />
sgdisk --zap-all $DRIVE<br />
<br />
sgdisk --clear \<br />
--new=1:0:+550MiB --typecode=1:ef00 --change-name=1:EFI \<br />
--new=2:0:+8GiB --typecode=2:8200 --change-name=2:cryptswap \<br />
--new=3:0:0 --typecode=2:8200 --change-name=3:cryptsystem \<br />
$DRIVE<br />
<br />
mkfs.fat -F32 -n EFI /dev/disk/by-partlabel/EFI<br />
<br />
cryptsetup luksFormat --align-payload=8192 -s 256 -c aes-xts-plain64 /dev/disk/by-partlabel/cryptsystem<br />
<br />
cryptsetup open /dev/disk/by-partlabel/cryptsystem system<br />
<br />
cryptsetup open --type plain --key-file /dev/urandom /dev/disk/by-partlabel/cryptswap swap<br />
<br />
mkswap -L swap /dev/mapper/swap<br />
<br />
swapon -L swap<br />
<br />
mkfs.btrfs --force --label system /dev/mapper/system<br />
<br />
o=defaults,x-mount.mkdir<br />
<br />
o_btrfs=$o,compress=lzo,ssd,noatime<br />
<br />
mount -t btrfs LABEL=system /mnt<br />
<br />
btrfs subvolume create /mnt/root<br />
<br />
btrfs subvolume create /mnt/home<br />
<br />
btrfs subvolume create /mnt/snapshots<br />
<br />
umount -R /mnt<br />
<br />
mount -t btrfs -o subvol=root,$o_btrfs LABEL=system /mnt<br />
<br />
mount -t btrfs -o subvol=home,$o_btrfs LABEL=system /mnt/home<br />
<br />
mount -t btrfs -o subvol=snapshots,$o_btrfs LABEL=system /mnt/.snapshots<br />
<br />
pacstrap /mnt base<br />
<br />
genfstab -L -p /mnt >> /mnt/etc/fstab<br />
<br />
sed -i "s+LABEL=swap+/dev/mapper/swap" /etc/fstab_labels<br />
<br />
systemd-nspawn -bD /mnt<br />
<br />
echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen<br />
<br />
locale-gen<br />
<br />
localectl set-locale LANG=en_US.UTF-8<br />
<br />
timedatectl set-ntp 1<br />
<br />
timedatectl set-timezone America/Los_Angeles<br />
<br />
hostnamectl set-hostname myhostname<br />
<br />
echo "127.0.1.1 myhostname.localdomain myhostname" >> /etc/hosts<br />
<br />
pacman -Syu base-devel btrfs-progs iw gptfdisk zsh vim terminus-font<br />
</nowiki>}}<br />
<br />
== Quick and Dirty ==<br />
<br />
{{Note|an extra example and may be moved to its own wiki page later}}<br />
<br />
This is the approximate process I follow if I want to bring up Arch on, say, an old laptop for a quick purpose built test machine, etc. It's not an install that I consider long term maintainable since rollbacks aren't implemented, nor is there any encryption, but it's a good example of how simple installation can be.<br />
<br />
{{bc|<nowiki><br />
DRIVE=/dev/DRIVEID<br />
sgdisk --zap-all $DRIVE<br />
mkfs.btrfs -f $DRIVE<br />
mount -t btrfs $DRIVE /mnt<br />
pacstrap /mnt base<br />
systemd-nspawn -bD /mnt<br />
echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen<br />
locale-gen<br />
localectl set-locale LANG=en_US.UTF-8<br />
timedatectl set-ntp 1<br />
timedatectl set-timezone America/Los_Angeles<br />
hostnamectl set-hostname myhostname<br />
poweroff<br />
arch-chroot /mnt<br />
grub-install --root-directory=/mnt $DRIVE<br />
grub-mkconfig -o /mnt/boot/grub/grub.cfg<br />
exit<br />
reboot<br />
</nowiki>}}</div>Altercationhttps://wiki.archlinux.org/index.php?title=User:Altercation/Bullet_Proof_Arch_Install&diff=458971User:Altercation/Bullet Proof Arch Install2016-12-10T17:39:12Z<p>Altercation: /* Quick and Dirty */</p>
<hr />
<div>This page is a summary of the current process I follow when installing Arch on a new laptop or desktop. My process varies over time, but this serves as my "state of the art" best practice recommendations. I'm open to feedback and suggestions for improvements.<br />
<br />
{{Note|This is entirely based on my own opinions and research. It is opinionated about the best way to do things given the current state of the kernel, hardware availability, and utilities, filesystems, etc. I will explain my rationale for specific choices and provide links to other sources of information (on the Arch wiki or external) where useful.}}<br />
<br />
== Objectives ==<br />
<br />
The goals of my standard "bullet proof" Arch Linux installation are:<br />
<br />
* Benefit from Arch's rolling release model while mitigating any risk of system corruption or data loss due to failed upgrades<br />
* Minimize risk due to hardware failure or total system loss (e.g. theft or physical destruction)<br />
* Make system rollbacks easy and procedural, using a standard setup and methodology for recovery of previous system (and user data) states<br />
<br />
=== Why not the Arch Install instructions? ===<br />
<br />
The [[Installation guide|Arch Linux installation instructions]] are an excellent, general starting point and you should read and understand them. That being said, they are designed to map to a very, very broad set of installation scenarios. I am interested in a very specific type of installation (daily use desktops and laptops in this article) and I have a strong set of opinions about the "right" or "best practice" way to set up my own working systems.<br />
<br />
These instructions, then, are much more prescriptive and have strong suggestions or directions about how (and why) one should use a particular method during Arch Linux installation.<br />
<br />
=== Key differences from the stock Arch install instructions ===<br />
<br />
How these instructions differ from the standard Arch guidance:<br />
<br />
* We are encrypting the entire system but not using LVM as is often recommended (see the encryption section below for details about why we are not using it).<br />
* I use labels and avoid UUIDs where possible to make switching to an alternate recovery drive easier.<br />
* I skip arch-chroot and simply boot the new system ('''not''' reboot, just boot) from within the install environment using {{Man|1|systemd-nspawn}} which enables the *ctl commands to work (and systemd services to be enabled properly without need for a system reboot)<br />
* I use the various systemd *ctl commands (hostnamectl, timedatectl, localectl, etc.) to configure the system<br />
* I use the systemd mkinitcpio hooks in lieu of the legacy hooks.<br />
* I use BTRFS exclusively for root and home partitions for its backup capabilities.<br />
* I recommend and use secure boot (but not with the Microsoft keys) to minimize risk due to the unavoidably unencrypted EFI partition.<br />
<br />
== Assumptions ==<br />
<br />
These instructions presuppose the following:<br />
<br />
* fairly new hardware (these instructions may work on older hardware, but there may be unusual issues that crop up... if you aren't comfortable handling those situations you should consider a more "traditional" Arch Linux install (e.g. using grub, LVM, ext4, etc.)<br />
* [[Unified Extensible Firmware Interface|UEFI support]] (BIOS system install is also possible with some modification of these instructions, but this has not yet been detailed here)<br />
* probably an [[Solid State Drives|SSD]].<br />
* some familiarity with Arch, or at least some experience with Linux, will help<br />
<br />
{{Warning|I am assuming you are going to single boot (not dual boot) and that you are '''willing to wipe all data from the install drive.''' If that is not the case, do not proceed with these instructions as following them '''will effectively destroy any data (and other operating systems) on the installation target drive.'''}}<br />
<br />
== Prerequisites ==<br />
<br />
You must have a recent copy of the Arch install USB. See [[:Category:Getting and installing Arch]] for general information and [[USB flash installation media]] for specific details on creating a USB Arch installation drive.<br />
<br />
You should also have a reasonable amount of time in which to complete the installation. Novice users will want to budget a couple hours. Experienced users will ''know'' to budget a couple hours.<br />
<br />
== Preparation ==<br />
<br />
=== Boot from USB Drive ===<br />
<br />
Boot your system from your prepared [[USB flash installation media|Arch Linux USB drive]]. It is important that you boot in EFI mode, not legacy BIOS compatibility mode. See the [[Unified Extensible Firmware Interface|UEFI]] article for more information about checking boot mode and ensuring you are booting using EFI.<br />
<br />
=== Bring up the network ===<br />
<br />
If you booted into a system with an ethernet cable plugged in, chances are you're up and running. If you need to use wireless instead, {{ic|wifi-menu}} will more often than not work without trouble. If those don't work, see [[Installation guide#Connect to the Internet|the Arch installation guide section on connecting to the internet]].<br />
<br />
=== Select Drive ===<br />
<br />
I like to use the [[Core utilities#lsblk|{{ic|1=lsblk}}]] command to bring up a quick list of the block devices on the system and identify existing partition structures and sizes, as well as mount points. If you don't already use it, I recommend [[Core utilities#lsblk|{{ic|1=lsblk}}]] when you need information on any given drive or partition. It's useful for polling UUIDs as well. For example, the following command gives you a clearly formatted summary of all block devices, their partition labels, filesystem lables, UUIDs and partition UUIDS: {{ic|lsblk -o +LABEL,PARTLABEL,UUID,PARTUUID}}<br />
<br />
In any case, the plain command without options should be enough to identify the drive you will install to (for example {{ic|1=/dev/sda}} or {{ic|1=/dev/nvme0n1}}:<br />
<br />
# lsblk<br />
<br />
=== Wipe Drive Securely (optional) ===<br />
<br />
While it is not necessary, given that this process will go through the trouble of encrypting the main system partition, it makes sense to do a secure wipe of the drive. This is more or less directly from [[Dm-crypt/Drive preparation#dm-crypt wipe on an empty disk or partition]].<br />
<br />
{{Warning|Be certain of your target device selection as we will be '''wiping this drive''' (either securely or, at minimum, destroying all existing partition data).}}<br />
<br />
First, create a temporary encrypted container the full disk ({{ic|sdX}}) to be encrypted, e.g. using default encryption parameters and a random key via the {{ic|--key-file /dev/{u}random}} option (see also [[Random number generation]]):<br />
<br />
# cryptsetup open --type plain /dev/sdXY container --key-file /dev/urandom<br />
<br />
{{Note|An interesting page addressing myths about /dev/urandom can be [http://www.2uo.de/myths-about-urandom/ found here]}}<br />
<br />
Second, check the container exists:<br />
<br />
{{hc|# fdisk -l|Disk /dev/mapper/container: XXXX MB, XXXXXXXXXX bytes<br />
...<br />
Disk /dev/mapper/container does not contain a valid partition table}}<br />
Wipe the container with zeros. A use of {{ic|1=if=/dev/urandom}} is '''not''' required as the encryption cipher itself generates randomness.<br />
{{hc|# dd <nowiki>if=/dev/zero of=/dev/mapper/container status=progress bs=1M</nowiki>|<br />
dd: writing to ‘/dev/mapper/container’: No space left on device}}<br />
<br />
{{Tip|<br />
* Using ''dd'' with the {{ic|1=bs=}} option, e.g. {{ic|1=bs=1M}} as above, is frequently used to increase disk throughput of the operation.<br />
* To perform a check of the operation, zero the partition before creating the wipe container. After the wipe command {{ic|blockdev --getsize64 ''/dev/mapper/container''}} can be used to get the exact container size as root. Now ''od'' can be used to spotcheck whether the wipe overwrote the zeroed sectors, e.g. {{ic|od -j ''containersize - blocksize''}} to view the wipe completed to the end.}}<br />
<br />
Finally, close the temporary container:<br />
<br />
# cryptsetup close container<br />
<br />
== Partition & Format Drive ==<br />
<br />
=== Understanding some basics about disks, partitions, and filesystems ===<br />
<br />
Think of your drive like a big empty building, no rooms. This is your plain physical drive (either a spinning platter drive or an SSD). Next imagine that to make it useful, we divide the building into apartments. In our analogy the apartments are '''partitions''' of the drive.<br />
<br />
Imagine also that there are a couple different standard methods of creating layout maps to the apartments. These plans are standardized so that the public services that have to access the building regularly (like the fire and police, for example) understand how to find the apartment entrances. In the world of partitioning, the equivalent is the "partition table scheme". The two common schemes are called "MBR" (Master Boot Record, older) and "GPT" (GUID Partition Table, newer). We will be using the new GPT scheme.<br />
<br />
Finally, imagine that the apartments are just empty shells. The act of building walls and laying out the functional structure of the apartments is equivalent to formatting our disk partitions with a filesystem. And just as different layouts may be more or less efficient, or have other different functional characteristics, so to filesystems have different attributes that make them useful in different ways.<br />
<br />
=== Our partition plans ===<br />
<br />
We will take our physical drive and divide it into three partitions. These partitions each serve a distinct purpose. All but the first and smallest, the EFI partition, will be encrypted. For security, if your system supports Secure Boot, you may choose to cryptographically sign the data stored on the EFI partition so that any tampering will be evident, despite the lack of encryption on that partition.<br />
<br />
{{Note|Again, we're assuming an UEFI installation (not legacy BIOS) and a GPT (not MBR) partition structure. If none of that made sense, best to start with the [[Partitioning]] article or do some test installs of Arch first. '''Partitioning is, in my opinion, one of the areas that is most confusing for the new Arch user.''' Additionally, there is a lot "received wisdom" and cargo-cult assumption making about how best to partition. Working through some of the "this is how it's always been done" tutorials isn't necessarily a bad thing... In many cases the way it has always been done has some sound reasoning behind it, despite being cargo-culted half the time. That being said, the method presented here is different from that in most of the Arch wiki partitioning methodologies.}}<br />
<br />
We will not be using LVM. You read a lot about LUKS and LVM and it all gets a bit complicated (LVM on LUKS, LUKS on LVM, etc.). LVM is a "logical volume manager" and abstracts physical devices (drives) into virtual devices, for easier management. It's a good idea but we will be using btrfs to effectively achieve the same results and really don't need the overhead of LVM.<br />
<br />
=== Partition Summary ===<br />
<br />
* 1: EFI - The UEFI 'bios" will look for this FAT32 formatted partition and either locate a default bootloader or will locate a specific EFI boot entry on it. This partition is by necessity not encrypted (unless the drive it is on has been encrypted as a "self encrypting drive")<br />
* 2: Swap - Used by Linux to swap out pages of memory from RAM to disk. Despite debate in this area, it is advisable to have at least some swap space, even it you are not planning on using hibernation on your machine. The Arch wiki is unfortunately rather too brief in its own [[Swap|swap article]] so I recommend the [https://docs.fedoraproject.org/en-US/Fedora/14/html/Storage_Administration_Guide/ch-swapspace.html Fedora documentation on swap] for a good overview on determining the right swap partition size.<br />
* 3: System - This will hold our root and home data. It will be formatted as BTRFS and will use subvolumes to manage snapshots of the current root and home contents.<br />
<br />
=== Visual overview of our partitions, filesystems, and contents ===<br />
<br />
This is a visual summary of our partions (inc. size information), encryption, filesystems, and a summary of the contents of each container.<br />
<br />
{| class="wikitable"<br />
| style="vertical-align: top; padding:1em" | '''Partition 1 (EFI)'''<br />
550MiB+<br />
{| style="border: 1px solid black; background: #DACEF2; margin: 1em;"<br />
! FAT32<br />
|-<br />
|kernel & initramfs<br />
(signed if using secure boot)<br />
|}<br />
| style="vertical-align: top; padding:1em" | '''Partition 2 (Swap)'''<br />
w/ Hibernate: Equal RAM,<br />
w/o Hibernate: min 8GB<br />
{| style="border: 1px solid black; background: #F2ECCE; margin: 1em;"<br />
|-<br />
! dm-crypt<br />
{| style="border: 1px solid black; background: #DACEF2; margin: 1em;"<br />
| SWAP<br />
|}<br />
|}<br />
| style="vertical-align: top; padding:1em" | '''Partition 3 (System)'''<br />
Remaining Space<br />
{| style="border: 1px solid black; background: #F2ECCE; margin: 1em;"<br />
|-<br />
! LUKS dm-crypt<br />
<br />
{| style="border: 1px solid black; background: #DACEF2; margin: 1em;"<br />
| BTRFS Top Level Subvolume<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Root Subvolume<br />
|}<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Home Subvolume<br />
|}<br />
<br />
{| style="border: 1px solid black; background: #E0CEF2; margin: 1em;"<br />
| BTRFS Snapshots Subvolume<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Root Snapshot Subvolume(s)<br />
|}<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Home Snapshot Subvolume(s)<br />
|}<br />
<br />
|}<br />
<br />
|}<br />
<br />
|}<br />
<br />
|}<br />
<br />
=== Partition Drive ===<br />
<br />
There are many utilities available for [[Partitioning]]. Because we are using Arch Linux and the command line doesn't hurt us (it makes us stronger) we will be using pure, non-interactive command line tools for this. Specifically, we will be using the utility [[Fdisk#Using_sgdisk|sgdisk]] from the {{Pkg|gptfdisk}} package. The [[Fdisk|fdisk]] utility now also supports GPT partitioned drives, so it would be an alternative. [[Fdisk#Using_sgdisk|sgdisk]] is available by default on the standard Arch install iso that you use to make your bootable USB drive.<br />
<br />
First, select the drive you will install to. Make sure you have selected the correct drive!. Again, a quick {{ic|lsblk}} will work here.<br />
<br />
# $DRIVE=/dev/DRIVEID<br />
<br />
(replace /dev/DRIVEID with the correct value, for example /dev/sda, /dev/nvme0n1, etc.)<br />
<br />
If you didn't securely wipe the drive already, it's worth "zapping" it using [[Fdisk#Using_sgdisk|sgdisk]] to remove any lingering legacy partition information. If you already wiped the drive you can skip this command (though it won't hurt to run it again).<br />
<br />
{{Warning|'''This command will also effectively erase the selected drive!'''}}<br />
<br />
# sgdisk --zap-all $DRIVE<br />
<br />
The following command will then create all three partitions in one go. '''It will also effectively erase the selected drive!'''<br />
<br />
# sgdisk --clear \<br />
--new=1:0:+550MiB --typecode=1:ef00 --change-name=1:EFI \<br />
--new=2:0:+8GiB --typecode=2:8200 --change-name=2:cryptswap \<br />
--new=3:0:0 --typecode=2:8200 --change-name=3:cryptsystem \<br />
$DRIVE<br />
<br />
It is worth noting that the "--change-name" values are, in this case, creating GPT "partition labels". You can subsequently see these by using the {{ic|lsblk -o +PARTLABEL}} command. It is good to use "EFI" for the efi partition. I am not aware of UEFI implementations that actively use the label for identification of the EFI partition, but it is possible that some do (UEFI bios implementations are not always consistent or to spec). The other two names are entirely "arbitrary". There is nothing special about calling them cryptswap and cryptsystem; they are simply good, clear names that remind us of the purpose of this partition and what it contains (for example, "cryptswap" suggests "this partition is for swap, and is encrypted").<br />
<br />
One final note about partition labels: we want them to be unique on your system. If for some reason there is already a GPT partition with the name EFI on another drive on your system, either change that partition name or use something besides "EFI" to avoid a namespace collision.<br />
<br />
Note also, that the backslashes at the end of each line can be omitted if you are writing the command on one long line instead. Those simply allow the splitting of a single command onto multiple lines.<br />
<br />
=== Format EFI Partition ===<br />
<br />
Next up: format the first (EFI) partition using the (required) FAT32 filesystem.<br />
<br />
# mkfs.fat -F32 -n EFI /dev/disk/by-partlabel/EFI<br />
<br />
Note that we here make use of the partition label we just assigned. I prefer doing this since it simplifies scripts significantly for me and makes them, in my opinion, more readable.<br />
<br />
=== Encrypt System Partition ===<br />
<br />
Encrypt the main partition. Use a good passphrase. Note that the "--align-payload" value has been used as per [http://www.spinics.net/lists/dm-crypt/msg02421.html this suggestion/explanation] on the dm-crypt mailing list.<br />
<br />
Note also that I selected the encryption algorithm and key size using cryptsetup benchmark. See the [[Dm-crypt/Device_encryption]] article for more details.<br />
<br />
# cryptsetup luksFormat --align-payload=8192 -s 256 -c aes-xts-plain64 /dev/disk/by-partlabel/cryptsystem<br />
<br />
After creating the encrypted container, open it. Again, note the use of the partition label to identify the drive. Additionally, note that once we open this device we are giving it a name of "system." Thus "cryptsystem" is the encrypted system partition, while "system" is the name we are using once it has been opened in an unencrypted state. These names are arbitrary (Linux doesn't care what we use) but they help us keep things organized during this process.<br />
<br />
# cryptsetup open /dev/disk/by-partlabel/cryptsystem system<br />
<br />
=== Bring Up Encrypted Swap ===<br />
<br />
Finally we create encrypted swap. In this example we are not enabling hibernation. I will provide information on how to enable hibernation separately. Again, using partition labels to identify the partition and going from "cryptswap" to just "swap".<br />
<br />
We are not using LUKS here (which effectively makes dm-crypt easier to use). We're just using plain dm-crypt to encrypt the swap partition using a random key.<br />
<br />
# cryptsetup open --type plain --key-file /dev/urandom /dev/disk/by-partlabel/cryptswap swap<br />
# mkswap -L swap /dev/mapper/swap<br />
# swapon -L swap<br />
<br />
=== Create and mount BTRFS subvolumes ===<br />
<br />
Now on to the main attraction: creating our BTRFS subvolume structure. While BTRFS can be set up like any other filesystem (single command, just use the created file system directly), we're going to use the power of BTRFS to enable snapshotting our system state efficiently and rollbacks as necessary.<br />
<br />
First we create a top-level BTRFS subvolume. Note that the top-level entity in BTRFS nomenclature is still referred to as a '''sub'''volume, despite being at the top-level.<br />
<br />
We will create and mount this subvolume, create some new subvolumes inside it, and then switch to those subvolumes as our proper, mounted filesystems. Doing this will enable us to treat our root filesystem as a snapshotable object.<br />
<br />
Top-level subvolume creation.<br />
<br />
# mkfs.btrfs --force --label system /dev/mapper/system<br />
<br />
Temporarily mount our top-level volume for further subvolume creation. Note that the variable 'o' in this case is our default set of options for any given filesystem mount, while "o_btrfs" are those plus some options specific to btrfs. The default option "x-mount.mkdir" is a neat trick that allows us to skip the creation of directories for mountpoints (they will be created automatically). We assume /mnt as the standard mount point, as in a normal Arch Linux installation.<br />
<br />
# o=defaults,x-mount.mkdir<br />
# o_btrfs=$o,compress=lzo,ssd,noatime<br />
<br />
Note the use of our filesystem label to mount our subvolume. This is distinct from the partition labels used earlier. See the Arch wiki article on [[Persistent_block_device_naming]] for more information.<br />
<br />
# mount -t btrfs LABEL=system /mnt<br />
<br />
Now we create the subvolumes which will actually be mounted in our running system:<br />
<br />
# btrfs subvolume create /mnt/root<br />
# btrfs subvolume create /mnt/home<br />
# btrfs subvolume create /mnt/snapshots<br />
<br />
Then we unmount everything...<br />
<br />
# umount -R /mnt<br />
<br />
And remount just the subvolumes under our top-level subvolume (which remains unmounted unless we need to do "surgery" and rollback to a previous system system):<br />
<br />
# mount -t btrfs -o subvol=root,$o_btrfs LABEL=system /mnt<br />
<br />
Before mounting the home and snapshots subvolumes, let's walk through that command so we understand what it's doing:<br />
<br />
The 'mount -t btrfs' just specifies that our filesystem is of type BTRFS. This is often not necessary since mount will attempt to identify the filesystem type, but being explicit is often the best strategy with command line utilities, so we identify the type here.<br />
<br />
We use our previously defined mount options with the $o_btrfs variable and add the additional option "subvol=root" (separating it from our other defaults with a comma, of course). The next part of the command is "LABEL=system". Combined this reads as "mount the filesystem with the 'system' label, and use the 'root' subvolume within that".<br />
<br />
Finally, all this gets mounted at our install root, which in this case is "/mnt".<br />
<br />
Now let's pick back up and mount our home and snapshots subvolumes. Note that while the subvolume name is "snapshots", we will mount it at ".snapshots" (note dot prefix for the mount point). This will keep our root directory listing clean but will still make it available at a reasonable mount location.<br />
<br />
# mount -t btrfs -o subvol=home,$o_btrfs LABEL=system /mnt/home<br />
# mount -t btrfs -o subvol=snapshots,$o_btrfs LABEL=system /mnt/.snapshots<br />
<br />
It it worth noting that in each case we are telling mount to use the same filesystem, namely the one labeled "system". However in each case we are also telling it to look for a different subvolume in that filesystem (via the "subvol=" option).<br />
<br />
With this done, we can move on to installing the actual system.<br />
<br />
=== Mount EFI partition ===<br />
<br />
# mount LABEL=EFI /mnt/boot<br />
<br />
== Installation of Base Arch Linux System ==<br />
<br />
We are currently running off the Arch installer root filesystem. We will first use the 'pacstrap' utility to start our installation and then we will boot into our new minimal system using systemd-nspawn.<br />
<br />
=== Install base package group ===<br />
<br />
# pacstrap /mnt base<br />
<br />
=== fstab Generation and Modification ===<br />
<br />
{{Note|In a simpler, non encrypted configuration it is possible to skip making an fstab altogether due to a standard known as the [https://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/ Discoverable Partitions Spec]. However given the complexity of our encrypted, btrfs subvolume configuration, we require an fstab at this time. It is possible that in future we might feasibly do away with the fstab almost entirely in this setup (see the [https://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/#whataboutautomaticmountingofbtrfssubvolumestovarhomeandsoon 'What about automatic mounting of btrfs subvolumes'] section on that page).}}<br />
<br />
Create an [[fstab]] filesystem table file, using labels (-L) to identify the filesystems.<br />
<br />
# genfstab -L -p /mnt >> /mnt/etc/fstab<br />
<br />
I prefer to use labels as this makes the system more portable to a backup drive. You should end up with something that looks pretty close to this:<br />
<br />
{{hc|# cat /mnt/etc/fstab|<nowiki><br />
# /dev/mapper/system UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=system / btrfs rw,noatime,compress=lzo,ssd,space_cache,subvolid=257,subvol=/root,subvol=root 0 0<br />
<br />
# /dev/mapper/system UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=system /home btrfs rw,noatime,compress=lzo,ssd,space_cache,subvolid=258,subvol=/home,subvol=home 0 0<br />
<br />
# /dev/mapper/system UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=system /.snapshots btrfs rw,noatime,compress=lzo,ssd,space_cache,subvolid=259,subvol=/snapshots,subvol=snapshots 0 0<br />
<br />
# /dev/nvme0n1p1 UUID=xxxx-xxxx<br />
LABEL=EFI /boot/EFI vfat rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro 0 2<br />
<br />
# /dev/mapper/swap UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=swap none swap defaults 0 0<br />
</nowiki>}}<br />
<br />
There is one problem, however. Swap will not remount this way (the plain dm-crypt partition with a random key will not have a label when it is recreated on reboot). You will have to change that line from this:<br />
<br />
{{bc|<nowiki>LABEL=swap none swap defaults 0 0</nowiki>}}<br />
<br />
to this:<br />
<br />
{{bc|/dev/mapper/swap none swap defaults 0 0}}<br />
<br />
This will ensure that the mapped device is opened as swap successfully. The other lines may remain unchanged.<br />
<br />
==== Use {{ic|sed}} instead ====<br />
<br />
As a (scriptable) alternative to the manual editing of your {{ic|/etc/fstab}} you could use {{Man|1|sed}} to edit the file in place:<br />
<br />
# sed -i s+LABEL=swap+/dev/mapper/swap+ /mnt/etc/fstab_labels<br />
<br />
=== Boot into new system ===<br />
<br />
{{Warning|While this works, I am fairly certain I'll want to double check some things before declaring this step final. Specifically I want to consider some bind mounts and whether there is anything that should be r/w instead of r/o as is normal in a systemd-nspawn container.}}<br />
<br />
# systemd-nspawn -bD /mnt<br />
<br />
This will boot your new base Arch Linux system. After the standard boot messages scroll by you will be presented with a login (enter {{ic|root}} and hit enter to login).<br />
<br />
=== Generate and set locale ===<br />
<br />
Next, edit and uncomment your desired locale(s) from {{ic|/etc/locale.gen}}. We use {{ic|vi}} in the example below, but you could use a simpler editor such as {{ic|nano}} if you wish.<br />
<br />
{{hc|vi /etc/locale.gen|<nowiki><br />
...<br />
#en_PH.UTF-8 UTF-8<br />
#en_PH ISO-8859-1<br />
#en_SG.UTF-8 UTF-8<br />
#en_SG ISO-8859-1<br />
#en_US.UTF-8 UTF-8<br />
#en_US ISO-8859-1<br />
#en_ZA.UTF-8 UTF-8<br />
#en_ZA ISO-8859-1<br />
#en_ZM UTF-8<br />
...<br />
</nowiki>}}<br />
<br />
Changing it to (for en_US.UTF-8 as a locale in this example):<br />
<br />
{{bc|<nowiki><br />
...<br />
#en_PH.UTF-8 UTF-8<br />
#en_PH ISO-8859-1<br />
#en_SG.UTF-8 UTF-8<br />
#en_SG ISO-8859-1<br />
en_US.UTF-8 UTF-8<br />
#en_US ISO-8859-1<br />
#en_ZA.UTF-8 UTF-8<br />
#en_ZA ISO-8859-1<br />
#en_ZM UTF-8<br />
...<br />
</nowiki>}}<br />
<br />
Alternately one could simply append a known value to the {{ic|/etc/locale.gen}} file:<br />
<br />
# echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen<br />
<br />
After either method, one runs the {{ic|locale-gen}} command to generate the locale files:<br />
<br />
# locale-gen<br />
<br />
Finally we use {{Man|1|systemd-firstboot}} or {{Man|1|localectl}} to set the system locale. Each of these effectively does the same thing which is to simply write to {{ic|/etc/locale.conf}} (which can simply be edited directly as per standard Arch install instructions).<br />
<br />
==== With systemd-firstboot ====<br />
<br />
{{Man|1|systemd-firstboot}} will prompt us for selection from our generated locales. It will only work if there is no assigned system locale. If you wish to make changes afterward you can use {{Man|1|localectl}}<br />
<br />
# systemd-firstboot --prompt-locale<br />
<br />
==== With localectl ====<br />
<br />
This is an alternate to using {{ic|systemd-firstboot --prompt-locale}}. It may also be used subsequent to that command if further changes to the locale are desired.<br />
<br />
If you need a reminder of which locales have been installed (during this install or later during system changes), use {{ic|localectl list-locales}}:<br />
<br />
{{hc|<nowiki># localectl list-locales</nowiki>|en_US.UTF-8}}<br />
<br />
We then use {{ic|localectl set-locale}}:<br />
<br />
# localectl set-locale LANG=en_US.UTF-8<br />
<br />
=== Time and Date ===<br />
<br />
Unless you have a reason not to, we'll turn on NTP synchronization.<br />
<br />
# timedatectl set-ntp 1<br />
<br />
Then list timezones and pick one<br />
<br />
{{hc|<nowiki># timedatectl list-timezones</nowiki>|<nowiki><br />
...<br />
America/Kentucky/Louisville<br />
America/Kentucky/Monticello<br />
America/Kralendijk<br />
America/La_Paz<br />
America/Lima<br />
America/Los_Angeles<br />
America/Lower_Princes<br />
America/Maceio<br />
America/Managua<br />
America/Manaus<br />
America/Marigot<br />
America/Martinique<br />
America/Matamoros<br />
...<br />
</nowiki>}}<br />
# timedatectl set-timezone America/Los_Angeles<br />
<br />
=== Set hostname ===<br />
<br />
# hostnamectl set-hostname myhostname<br />
<br />
See the man page for {{Man|1|hostnamectl}} for other attributes that can be set. You might also add the hostname to {{Man|5|hosts}}:<br />
<br />
{{hc|/etc/hosts|<br />
127.0.0.1 localhost.localdomain localhost<br />
::1 localhost.localdomain localhost<br />
'''127.0.1.1 ''myhostname''.localdomain ''myhostname'''''<br />
}}<br />
<br />
Use {{ic|echo}} for a scriptable solution:<br />
<br />
# echo "127.0.1.1 myhostname.localdomain myhostname" >> /etc/hosts<br />
<br />
=== Network configuration ===<br />
<br />
Configure the network for the newly installed environment: see [[Network configuration]].<br />
<br />
For [[Wireless configuration]], [[Help:Reading#Installation of packages|install]] the {{Pkg|iw}}, {{Pkg|wpa_supplicant}}, and {{Pkg|dialog}} packages, as well as needed [[Wireless#Installing driver/firmware|firmware packages]].<br />
<br />
=== Base Package Installation ===<br />
<br />
We've already included the {{Grp|base}} group which is, strictly speaking, all you need to boot a minimal Arch Linux system. At this stage, however, we can install some useful utilities (and Xorg or Wayland, etc.).<br />
<br />
# pacman -Syu base-devel btrfs-progs iw gptfdisk zsh vim terminus-font<br />
<br />
=== Initramfs ===<br />
<br />
Creating a new ''initramfs'' is usually not required, because [[mkinitcpio]] was run on installation of the {{Pkg|linux}} package with ''pacstrap''. However we'll need to make some changes to the hooks used on our system. Additionally, I switched over to using the systemd hooks in mkinitcpio, so that is largely what you'll see in my example below.<br />
<br />
I recommend making a backup of your {{ic|/etc/mkinitcpio.conf}} file first:<br />
<br />
# mv /etc/mkinitcpio.conf /etc/mkinitcpio.conf.orig<br />
<br />
and then editing a new file to match the following contents:<br />
<br />
{{bc|<nowiki><br />
MODULES=""<br />
BINARIES=""<br />
FILES=""<br />
HOOKS="base systemd sd-vconsole modconf keyboard block filesystems btrfs sd-encrypt fsck"<br />
</nowiki>}}<br />
<br />
Finally, recreate the initramfs image:<br />
<br />
# mkinitcpio -p linux<br />
<br />
=== Bootloader ===<br />
<br />
{{Warning|THIS SECTION IN PROGRESS}}<br />
<br />
=== Root password ===<br />
<br />
Set the root [[password]]:<br />
<br />
# passwd<br />
<br />
=== Leave the systemd-nspawn environment ===<br />
<br />
Issue a poweroff to exit the nspawned environment:<br />
<br />
# poweroff<br />
<br />
This will return you the Arch installer environment where you can wrap up.<br />
<br />
=== Legacy boot loader ===<br />
<br />
If your system is not UEFI and you need to use a legacy installer like grub, it will need to be installed from within an arch-chroot generated chroot, not the systemd-nspawn running container. An example of this would be (assuming that the drive of the new system is at /dev/sdb):<br />
<br />
# arch-chroot /mnt<br />
# grub-install $DRIVE<br />
# grub-mkconfig -o /boot/grub/grub.cfg<br />
# exit<br />
<br />
== Command Summary ==<br />
<br />
The following are all critical commands (exluded: the initial drive wipe which is optional). It assumes you have successfully brought up networking prior to starting this sequence.<br />
<br />
{{bc|<nowiki><br />
<br />
$DRIVE=/dev/DRIVEID<br />
<br />
sgdisk --zap-all $DRIVE<br />
<br />
sgdisk --clear \<br />
--new=1:0:+550MiB --typecode=1:ef00 --change-name=1:EFI \<br />
--new=2:0:+8GiB --typecode=2:8200 --change-name=2:cryptswap \<br />
--new=3:0:0 --typecode=2:8200 --change-name=3:cryptsystem \<br />
$DRIVE<br />
<br />
mkfs.fat -F32 -n EFI /dev/disk/by-partlabel/EFI<br />
<br />
cryptsetup luksFormat --align-payload=8192 -s 256 -c aes-xts-plain64 /dev/disk/by-partlabel/cryptsystem<br />
<br />
cryptsetup open /dev/disk/by-partlabel/cryptsystem system<br />
<br />
cryptsetup open --type plain --key-file /dev/urandom /dev/disk/by-partlabel/cryptswap swap<br />
<br />
mkswap -L swap /dev/mapper/swap<br />
<br />
swapon -L swap<br />
<br />
mkfs.btrfs --force --label system /dev/mapper/system<br />
<br />
o=defaults,x-mount.mkdir<br />
<br />
o_btrfs=$o,compress=lzo,ssd,noatime<br />
<br />
mount -t btrfs LABEL=system /mnt<br />
<br />
btrfs subvolume create /mnt/root<br />
<br />
btrfs subvolume create /mnt/home<br />
<br />
btrfs subvolume create /mnt/snapshots<br />
<br />
umount -R /mnt<br />
<br />
mount -t btrfs -o subvol=root,$o_btrfs LABEL=system /mnt<br />
<br />
mount -t btrfs -o subvol=home,$o_btrfs LABEL=system /mnt/home<br />
<br />
mount -t btrfs -o subvol=snapshots,$o_btrfs LABEL=system /mnt/.snapshots<br />
<br />
pacstrap /mnt base<br />
<br />
genfstab -L -p /mnt >> /mnt/etc/fstab<br />
<br />
sed -i "s+LABEL=swap+/dev/mapper/swap" /etc/fstab_labels<br />
<br />
systemd-nspawn -bD /mnt<br />
<br />
echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen<br />
<br />
locale-gen<br />
<br />
localectl set-locale LANG=en_US.UTF-8<br />
<br />
timedatectl set-ntp 1<br />
<br />
timedatectl set-timezone America/Los_Angeles<br />
<br />
hostnamectl set-hostname myhostname<br />
<br />
echo "127.0.1.1 myhostname.localdomain myhostname" >> /etc/hosts<br />
<br />
pacman -Syu base-devel btrfs-progs iw gptfdisk zsh vim terminus-font<br />
</nowiki>}}<br />
<br />
== Quick and Dirty ==<br />
<br />
{{Note|an extra example and may be moved to its own wiki page later}}<br />
<br />
This is the approximate process I follow if I want to bring up Arch on, say, an old laptop for a quick purpose built test machine, etc. It's not an install that I consider long term maintainable since rollbacks aren't implemented, nor is there any encryption, but it's a good example of how simple installation can be.<br />
<br />
{{bc|<nowiki><br />
DRIVE=/dev/DRIVEID<br />
sgdisk --zap-all $DRIVE<br />
mkfs.btrfs -f $DRIVE<br />
mount -t btrfs $DRIVE /mnt<br />
pacstrap /mnt base<br />
systemd-nspawn -bD /mnt<br />
echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen<br />
locale-gen<br />
localectl set-locale LANG=en_US.UTF-8<br />
timedatectl set-ntp 1<br />
timedatectl set-timezone America/Los_Angeles<br />
hostnamectl set-hostname myhostname<br />
poweroff<br />
arch-chroot /mnt<br />
grub-install --root-directory=/mnt $DRIVE<br />
grub-mkconfig -o /mnt/boot/grub/grub.cfg<br />
exit<br />
reboot<br />
</nowiki>}}</div>Altercationhttps://wiki.archlinux.org/index.php?title=User:Altercation/Bullet_Proof_Arch_Install&diff=458657User:Altercation/Bullet Proof Arch Install2016-12-06T18:42:54Z<p>Altercation: /* Create and mount BTRFS subvolumes */</p>
<hr />
<div>This page is a summary of the current process I follow when installing Arch on a new laptop or desktop. My process varies over time, but this serves as my "state of the art" best practice recommendations. I'm open to feedback and suggestions for improvements.<br />
<br />
{{Note|This is entirely based on my own opinions and research. It is opinionated about the best way to do things given the current state of the kernel, hardware availability, and utilities, filesystems, etc. I will explain my rationale for specific choices and provide links to other sources of information (on the Arch wiki or external) where useful.}}<br />
<br />
== Objectives ==<br />
<br />
The goals of my standard "bullet proof" Arch Linux installation are:<br />
<br />
* Benefit from Arch's rolling release model while mitigating any risk of system corruption or data loss due to failed upgrades<br />
* Minimize risk due to hardware failure or total system loss (e.g. theft or physical destruction)<br />
* Make system rollbacks easy and procedural, using a standard setup and methodology for recovery of previous system (and user data) states<br />
<br />
=== Why not the Arch Install instructions? ===<br />
<br />
The [[Installation guide|Arch Linux installation instructions]] are an excellent, general starting point and you should read and understand them. That being said, they are designed to map to a very, very broad set of installation scenarios. I am interested in a very specific type of installation (daily use desktops and laptops in this article) and I have a strong set of opinions about the "right" or "best practice" way to set up my own working systems.<br />
<br />
These instructions, then, are much more prescriptive and have strong suggestions or directions about how (and why) one should use a particular method during Arch Linux installation.<br />
<br />
=== Key differences from the stock Arch install instructions ===<br />
<br />
How these instructions differ from the standard Arch guidance:<br />
<br />
* We are encrypting the entire system but not using LVM as is often recommended (see the encryption section below for details about why we are not using it).<br />
* I use labels and avoid UUIDs where possible to make switching to an alternate recovery drive easier.<br />
* I skip arch-chroot and simply boot the new system ('''not''' reboot, just boot) from within the install environment using {{Man|1|systemd-nspawn}} which enables the *ctl commands to work (and systemd services to be enabled properly without need for a system reboot)<br />
* I use the various systemd *ctl commands (hostnamectl, timedatectl, localectl, etc.) to configure the system<br />
* I use the systemd mkinitcpio hooks in lieu of the legacy hooks.<br />
* I use BTRFS exclusively for root and home partitions for its backup capabilities.<br />
* I recommend and use secure boot (but not with the Microsoft keys) to minimize risk due to the unavoidably unencrypted EFI partition.<br />
<br />
== Assumptions ==<br />
<br />
These instructions presuppose the following:<br />
<br />
* fairly new hardware (these instructions may work on older hardware, but there may be unusual issues that crop up... if you aren't comfortable handling those situations you should consider a more "traditional" Arch Linux install (e.g. using grub, LVM, ext4, etc.)<br />
* [[Unified Extensible Firmware Interface|UEFI support]] (BIOS system install is also possible with some modification of these instructions, but this has not yet been detailed here)<br />
* probably an [[Solid State Drives|SSD]].<br />
* some familiarity with Arch, or at least some experience with Linux, will help<br />
<br />
{{Warning|I am assuming you are going to single boot (not dual boot) and that you are '''willing to wipe all data from the install drive.''' If that is not the case, do not proceed with these instructions as following them '''will effectively destroy any data (and other operating systems) on the installation target drive.'''}}<br />
<br />
== Prerequisites ==<br />
<br />
You must have a recent copy of the Arch install USB. See [[:Category:Getting and installing Arch]] for general information and [[USB flash installation media]] for specific details on creating a USB Arch installation drive.<br />
<br />
You should also have a reasonable amount of time in which to complete the installation. Novice users will want to budget a couple hours. Experienced users will ''know'' to budget a couple hours.<br />
<br />
== Preparation ==<br />
<br />
=== Boot from USB Drive ===<br />
<br />
Boot your system from your prepared [[USB flash installation media|Arch Linux USB drive]]. It is important that you boot in EFI mode, not legacy BIOS compatibility mode. See the [[Unified Extensible Firmware Interface|UEFI]] article for more information about checking boot mode and ensuring you are booting using EFI.<br />
<br />
=== Bring up the network ===<br />
<br />
If you booted into a system with an ethernet cable plugged in, chances are you're up and running. If you need to use wireless instead, {{ic|wifi-menu}} will more often than not work without trouble. If those don't work, see [[Installation guide#Connect to the Internet|the Arch installation guide section on connecting to the internet]].<br />
<br />
=== Select Drive ===<br />
<br />
I like to use the [[Core utilities#lsblk|{{ic|1=lsblk}}]] command to bring up a quick list of the block devices on the system and identify existing partition structures and sizes, as well as mount points. If you don't already use it, I recommend [[Core utilities#lsblk|{{ic|1=lsblk}}]] when you need information on any given drive or partition. It's useful for polling UUIDs as well. For example, the following command gives you a clearly formatted summary of all block devices, their partition labels, filesystem lables, UUIDs and partition UUIDS: {{ic|lsblk -o +LABEL,PARTLABEL,UUID,PARTUUID}}<br />
<br />
In any case, the plain command without options should be enough to identify the drive you will install to (for example {{ic|1=/dev/sda}} or {{ic|1=/dev/nvme0n1}}:<br />
<br />
# lsblk<br />
<br />
=== Wipe Drive Securely (optional) ===<br />
<br />
While it is not necessary, given that this process will go through the trouble of encrypting the main system partition, it makes sense to do a secure wipe of the drive. This is more or less directly from [[Dm-crypt/Drive preparation#dm-crypt wipe on an empty disk or partition]].<br />
<br />
{{Warning|Be certain of your target device selection as we will be '''wiping this drive''' (either securely or, at minimum, destroying all existing partition data).}}<br />
<br />
First, create a temporary encrypted container the full disk ({{ic|sdX}}) to be encrypted, e.g. using default encryption parameters and a random key via the {{ic|--key-file /dev/{u}random}} option (see also [[Random number generation]]):<br />
<br />
# cryptsetup open --type plain /dev/sdXY container --key-file /dev/urandom<br />
<br />
{{Note|An interesting page addressing myths about /dev/urandom can be [http://www.2uo.de/myths-about-urandom/ found here]}}<br />
<br />
Second, check the container exists:<br />
<br />
{{hc|# fdisk -l|Disk /dev/mapper/container: XXXX MB, XXXXXXXXXX bytes<br />
...<br />
Disk /dev/mapper/container does not contain a valid partition table}}<br />
Wipe the container with zeros. A use of {{ic|1=if=/dev/urandom}} is '''not''' required as the encryption cipher itself generates randomness.<br />
{{hc|# dd <nowiki>if=/dev/zero of=/dev/mapper/container status=progress bs=1M</nowiki>|<br />
dd: writing to ‘/dev/mapper/container’: No space left on device}}<br />
<br />
{{Tip|<br />
* Using ''dd'' with the {{ic|1=bs=}} option, e.g. {{ic|1=bs=1M}} as above, is frequently used to increase disk throughput of the operation.<br />
* To perform a check of the operation, zero the partition before creating the wipe container. After the wipe command {{ic|blockdev --getsize64 ''/dev/mapper/container''}} can be used to get the exact container size as root. Now ''od'' can be used to spotcheck whether the wipe overwrote the zeroed sectors, e.g. {{ic|od -j ''containersize - blocksize''}} to view the wipe completed to the end.}}<br />
<br />
Finally, close the temporary container:<br />
<br />
# cryptsetup close container<br />
<br />
== Partition & Format Drive ==<br />
<br />
=== Understanding some basics about disks, partitions, and filesystems ===<br />
<br />
Think of your drive like a big empty building, no rooms. This is your plain physical drive (either a spinning platter drive or an SSD). Next imagine that to make it useful, we divide the building into apartments. In our analogy the apartments are '''partitions''' of the drive.<br />
<br />
Imagine also that there are a couple different standard methods of creating layout maps to the apartments. These plans are standardized so that the public services that have to access the building regularly (like the fire and police, for example) understand how to find the apartment entrances. In the world of partitioning, the equivalent is the "partition table scheme". The two common schemes are called "MBR" (Master Boot Record, older) and "GPT" (GUID Partition Table, newer). We will be using the new GPT scheme.<br />
<br />
Finally, imagine that the apartments are just empty shells. The act of building walls and laying out the functional structure of the apartments is equivalent to formatting our disk partitions with a filesystem. And just as different layouts may be more or less efficient, or have other different functional characteristics, so to filesystems have different attributes that make them useful in different ways.<br />
<br />
=== Our partition plans ===<br />
<br />
We will take our physical drive and divide it into three partitions. These partitions each serve a distinct purpose. All but the first and smallest, the EFI partition, will be encrypted. For security, if your system supports Secure Boot, you may choose to cryptographically sign the data stored on the EFI partition so that any tampering will be evident, despite the lack of encryption on that partition.<br />
<br />
{{Note|Again, we're assuming an UEFI installation (not legacy BIOS) and a GPT (not MBR) partition structure. If none of that made sense, best to start with the [[Partitioning]] article or do some test installs of Arch first. '''Partitioning is, in my opinion, one of the areas that is most confusing for the new Arch user.''' Additionally, there is a lot "received wisdom" and cargo-cult assumption making about how best to partition. Working through some of the "this is how it's always been done" tutorials isn't necessarily a bad thing... In many cases the way it has always been done has some sound reasoning behind it, despite being cargo-culted half the time. That being said, the method presented here is different from that in most of the Arch wiki partitioning methodologies.}}<br />
<br />
We will not be using LVM. You read a lot about LUKS and LVM and it all gets a bit complicated (LVM on LUKS, LUKS on LVM, etc.). LVM is a "logical volume manager" and abstracts physical devices (drives) into virtual devices, for easier management. It's a good idea but we will be using btrfs to effectively achieve the same results and really don't need the overhead of LVM.<br />
<br />
=== Partition Summary ===<br />
<br />
* 1: EFI - The UEFI 'bios" will look for this FAT32 formatted partition and either locate a default bootloader or will locate a specific EFI boot entry on it. This partition is by necessity not encrypted (unless the drive it is on has been encrypted as a "self encrypting drive")<br />
* 2: Swap - Used by Linux to swap out pages of memory from RAM to disk. Despite debate in this area, it is advisable to have at least some swap space, even it you are not planning on using hibernation on your machine. The Arch wiki is unfortunately rather too brief in its own [[Swap|swap article]] so I recommend the [https://docs.fedoraproject.org/en-US/Fedora/14/html/Storage_Administration_Guide/ch-swapspace.html Fedora documentation on swap] for a good overview on determining the right swap partition size.<br />
* 3: System - This will hold our root and home data. It will be formatted as BTRFS and will use subvolumes to manage snapshots of the current root and home contents.<br />
<br />
=== Visual overview of our partitions, filesystems, and contents ===<br />
<br />
This is a visual summary of our partions (inc. size information), encryption, filesystems, and a summary of the contents of each container.<br />
<br />
{| class="wikitable"<br />
| style="vertical-align: top; padding:1em" | '''Partition 1 (EFI)'''<br />
550MiB+<br />
{| style="border: 1px solid black; background: #DACEF2; margin: 1em;"<br />
! FAT32<br />
|-<br />
|kernel & initramfs<br />
(signed if using secure boot)<br />
|}<br />
| style="vertical-align: top; padding:1em" | '''Partition 2 (Swap)'''<br />
w/ Hibernate: Equal RAM,<br />
w/o Hibernate: min 8GB<br />
{| style="border: 1px solid black; background: #F2ECCE; margin: 1em;"<br />
|-<br />
! dm-crypt<br />
{| style="border: 1px solid black; background: #DACEF2; margin: 1em;"<br />
| SWAP<br />
|}<br />
|}<br />
| style="vertical-align: top; padding:1em" | '''Partition 3 (System)'''<br />
Remaining Space<br />
{| style="border: 1px solid black; background: #F2ECCE; margin: 1em;"<br />
|-<br />
! LUKS dm-crypt<br />
<br />
{| style="border: 1px solid black; background: #DACEF2; margin: 1em;"<br />
| BTRFS Top Level Subvolume<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Root Subvolume<br />
|}<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Home Subvolume<br />
|}<br />
<br />
{| style="border: 1px solid black; background: #E0CEF2; margin: 1em;"<br />
| BTRFS Snapshots Subvolume<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Root Snapshot Subvolume(s)<br />
|}<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Home Snapshot Subvolume(s)<br />
|}<br />
<br />
|}<br />
<br />
|}<br />
<br />
|}<br />
<br />
|}<br />
<br />
=== Partition Drive ===<br />
<br />
There are many utilities available for [[Partitioning]]. Because we are using Arch Linux and the command line doesn't hurt us (it makes us stronger) we will be using pure, non-interactive command line tools for this. Specifically, we will be using the utility [[Fdisk#Using_sgdisk|sgdisk]] from the {{Pkg|gptfdisk}} package. The [[Fdisk|fdisk]] utility now also supports GPT partitioned drives, so it would be an alternative. [[Fdisk#Using_sgdisk|sgdisk]] is available by default on the standard Arch install iso that you use to make your bootable USB drive.<br />
<br />
First, select the drive you will install to. Make sure you have selected the correct drive!. Again, a quick {{ic|lsblk}} will work here.<br />
<br />
# $DRIVE=/dev/DRIVEID<br />
<br />
(replace /dev/DRIVEID with the correct value, for example /dev/sda, /dev/nvme0n1, etc.)<br />
<br />
If you didn't securely wipe the drive already, it's worth "zapping" it using [[Fdisk#Using_sgdisk|sgdisk]] to remove any lingering legacy partition information. If you already wiped the drive you can skip this command (though it won't hurt to run it again).<br />
<br />
{{Warning|'''This command will also effectively erase the selected drive!'''}}<br />
<br />
# sgdisk --zap-all $DRIVE<br />
<br />
The following command will then create all three partitions in one go. '''It will also effectively erase the selected drive!'''<br />
<br />
# sgdisk --clear \<br />
--new=1:0:+550MiB --typecode=1:ef00 --change-name=1:EFI \<br />
--new=2:0:+8GiB --typecode=2:8200 --change-name=2:cryptswap \<br />
--new=3:0:0 --typecode=2:8200 --change-name=3:cryptsystem \<br />
$DRIVE<br />
<br />
It is worth noting that the "--change-name" values are, in this case, creating GPT "partition labels". You can subsequently see these by using the {{ic|lsblk -o +PARTLABEL}} command. It is good to use "EFI" for the efi partition. I am not aware of UEFI implementations that actively use the label for identification of the EFI partition, but it is possible that some do (UEFI bios implementations are not always consistent or to spec). The other two names are entirely "arbitrary". There is nothing special about calling them cryptswap and cryptsystem; they are simply good, clear names that remind us of the purpose of this partition and what it contains (for example, "cryptswap" suggests "this partition is for swap, and is encrypted").<br />
<br />
One final note about partition labels: we want them to be unique on your system. If for some reason there is already a GPT partition with the name EFI on another drive on your system, either change that partition name or use something besides "EFI" to avoid a namespace collision.<br />
<br />
Note also, that the backslashes at the end of each line can be omitted if you are writing the command on one long line instead. Those simply allow the splitting of a single command onto multiple lines.<br />
<br />
=== Format EFI Partition ===<br />
<br />
Next up: format the first (EFI) partition using the (required) FAT32 filesystem.<br />
<br />
# mkfs.fat -F32 -n EFI /dev/disk/by-partlabel/EFI<br />
<br />
Note that we here make use of the partition label we just assigned. I prefer doing this since it simplifies scripts significantly for me and makes them, in my opinion, more readable.<br />
<br />
=== Encrypt System Partition ===<br />
<br />
Encrypt the main partition. Use a good passphrase. Note that the "--align-payload" value has been used as per [http://www.spinics.net/lists/dm-crypt/msg02421.html this suggestion/explanation] on the dm-crypt mailing list.<br />
<br />
Note also that I selected the encryption algorithm and key size using cryptsetup benchmark. See the [[Dm-crypt/Device_encryption]] article for more details.<br />
<br />
# cryptsetup luksFormat --align-payload=8192 -s 256 -c aes-xts-plain64 /dev/disk/by-partlabel/cryptsystem<br />
<br />
After creating the encrypted container, open it. Again, note the use of the partition label to identify the drive. Additionally, note that once we open this device we are giving it a name of "system." Thus "cryptsystem" is the encrypted system partition, while "system" is the name we are using once it has been opened in an unencrypted state. These names are arbitrary (Linux doesn't care what we use) but they help us keep things organized during this process.<br />
<br />
# cryptsetup open /dev/disk/by-partlabel/cryptsystem system<br />
<br />
=== Bring Up Encrypted Swap ===<br />
<br />
Finally we create encrypted swap. In this example we are not enabling hibernation. I will provide information on how to enable hibernation separately. Again, using partition labels to identify the partition and going from "cryptswap" to just "swap".<br />
<br />
We are not using LUKS here (which effectively makes dm-crypt easier to use). We're just using plain dm-crypt to encrypt the swap partition using a random key.<br />
<br />
# cryptsetup open --type plain --key-file /dev/urandom /dev/disk/by-partlabel/cryptswap swap<br />
# mkswap -L swap /dev/mapper/swap<br />
# swapon -L swap<br />
<br />
=== Create and mount BTRFS subvolumes ===<br />
<br />
Now on to the main attraction: creating our BTRFS subvolume structure. While BTRFS can be set up like any other filesystem (single command, just use the created file system directly), we're going to use the power of BTRFS to enable snapshotting our system state efficiently and rollbacks as necessary.<br />
<br />
First we create a top-level BTRFS subvolume. Note that the top-level entity in BTRFS nomenclature is still referred to as a '''sub'''volume, despite being at the top-level.<br />
<br />
We will create and mount this subvolume, create some new subvolumes inside it, and then switch to those subvolumes as our proper, mounted filesystems. Doing this will enable us to treat our root filesystem as a snapshotable object.<br />
<br />
Top-level subvolume creation.<br />
<br />
# mkfs.btrfs --force --label system /dev/mapper/system<br />
<br />
Temporarily mount our top-level volume for further subvolume creation. Note that the variable 'o' in this case is our default set of options for any given filesystem mount, while "o_btrfs" are those plus some options specific to btrfs. The default option "x-mount.mkdir" is a neat trick that allows us to skip the creation of directories for mountpoints (they will be created automatically). We assume /mnt as the standard mount point, as in a normal Arch Linux installation.<br />
<br />
# o=defaults,x-mount.mkdir<br />
# o_btrfs=$o,compress=lzo,ssd,noatime<br />
<br />
Note the use of our filesystem label to mount our subvolume. This is distinct from the partition labels used earlier. See the Arch wiki article on [[Persistent_block_device_naming]] for more information.<br />
<br />
# mount -t btrfs LABEL=system /mnt<br />
<br />
Now we create the subvolumes which will actually be mounted in our running system:<br />
<br />
# btrfs subvolume create /mnt/root<br />
# btrfs subvolume create /mnt/home<br />
# btrfs subvolume create /mnt/snapshots<br />
<br />
Then we unmount everything...<br />
<br />
# umount -R /mnt<br />
<br />
And remount just the subvolumes under our top-level subvolume (which remains unmounted unless we need to do "surgery" and rollback to a previous system system):<br />
<br />
# mount -t btrfs -o subvol=root,$o_btrfs LABEL=system /mnt<br />
<br />
Before mounting the home and snapshots subvolumes, let's walk through that command so we understand what it's doing:<br />
<br />
The 'mount -t btrfs' just specifies that our filesystem is of type BTRFS. This is often not necessary since mount will attempt to identify the filesystem type, but being explicit is often the best strategy with command line utilities, so we identify the type here.<br />
<br />
We use our previously defined mount options with the $o_btrfs variable and add the additional option "subvol=root" (separating it from our other defaults with a comma, of course). The next part of the command is "LABEL=system". Combined this reads as "mount the filesystem with the 'system' label, and use the 'root' subvolume within that".<br />
<br />
Finally, all this gets mounted at our install root, which in this case is "/mnt".<br />
<br />
Now let's pick back up and mount our home and snapshots subvolumes. Note that while the subvolume name is "snapshots", we will mount it at ".snapshots" (note dot prefix for the mount point). This will keep our root directory listing clean but will still make it available at a reasonable mount location.<br />
<br />
# mount -t btrfs -o subvol=home,$o_btrfs LABEL=system /mnt/home<br />
# mount -t btrfs -o subvol=snapshots,$o_btrfs LABEL=system /mnt/.snapshots<br />
<br />
It it worth noting that in each case we are telling mount to use the same filesystem, namely the one labeled "system". However in each case we are also telling it to look for a different subvolume in that filesystem (via the "subvol=" option).<br />
<br />
With this done, we can move on to installing the actual system.<br />
<br />
=== Mount EFI partition ===<br />
<br />
# mount LABEL=EFI /mnt/boot<br />
<br />
== Installation of Base Arch Linux System ==<br />
<br />
We are currently running off the Arch installer root filesystem. We will first use the 'pacstrap' utility to start our installation and then we will boot into our new minimal system using systemd-nspawn.<br />
<br />
=== Install base package group ===<br />
<br />
# pacstrap /mnt base<br />
<br />
=== fstab Generation and Modification ===<br />
<br />
{{Note|In a simpler, non encrypted configuration it is possible to skip making an fstab altogether due to a standard known as the [https://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/ Discoverable Partitions Spec]. However given the complexity of our encrypted, btrfs subvolume configuration, we require an fstab at this time. It is possible that in future we might feasibly do away with the fstab almost entirely in this setup (see the [https://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/#whataboutautomaticmountingofbtrfssubvolumestovarhomeandsoon 'What about automatic mounting of btrfs subvolumes'] section on that page).}}<br />
<br />
Create an [[fstab]] filesystem table file, using labels (-L) to identify the filesystems.<br />
<br />
# genfstab -L -p /mnt >> /mnt/etc/fstab<br />
<br />
I prefer to use labels as this makes the system more portable to a backup drive. You should end up with something that looks pretty close to this:<br />
<br />
{{hc|# cat /mnt/etc/fstab|<nowiki><br />
# /dev/mapper/system UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=system / btrfs rw,noatime,compress=lzo,ssd,space_cache,subvolid=257,subvol=/root,subvol=root 0 0<br />
<br />
# /dev/mapper/system UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=system /home btrfs rw,noatime,compress=lzo,ssd,space_cache,subvolid=258,subvol=/home,subvol=home 0 0<br />
<br />
# /dev/mapper/system UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=system /.snapshots btrfs rw,noatime,compress=lzo,ssd,space_cache,subvolid=259,subvol=/snapshots,subvol=snapshots 0 0<br />
<br />
# /dev/nvme0n1p1 UUID=xxxx-xxxx<br />
LABEL=EFI /boot/EFI vfat rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro 0 2<br />
<br />
# /dev/mapper/swap UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=swap none swap defaults 0 0<br />
</nowiki>}}<br />
<br />
There is one problem, however. Swap will not remount this way (the plain dm-crypt partition with a random key will not have a label when it is recreated on reboot). You will have to change that line from this:<br />
<br />
{{bc|<nowiki>LABEL=swap none swap defaults 0 0</nowiki>}}<br />
<br />
to this:<br />
<br />
{{bc|/dev/mapper/swap none swap defaults 0 0}}<br />
<br />
This will ensure that the mapped device is opened as swap successfully. The other lines may remain unchanged.<br />
<br />
==== Use {{ic|sed}} instead ====<br />
<br />
As a (scriptable) alternative to the manual editing of your {{ic|/etc/fstab}} you could use {{Man|1|sed}} to edit the file in place:<br />
<br />
# sed -i s+LABEL=swap+/dev/mapper/swap+ /mnt/etc/fstab_labels<br />
<br />
=== Boot into new system ===<br />
<br />
{{Warning|While this works, I am fairly certain I'll want to double check some things before declaring this step final. Specifically I want to consider some bind mounts and whether there is anything that should be r/w instead of r/o as is normal in a systemd-nspawn container.}}<br />
<br />
# systemd-nspawn -bD /mnt<br />
<br />
This will boot your new base Arch Linux system. After the standard boot messages scroll by you will be presented with a login (enter {{ic|root}} and hit enter to login).<br />
<br />
=== Generate and set locale ===<br />
<br />
Next, edit and uncomment your desired locale(s) from {{ic|/etc/locale.gen}}. We use {{ic|vi}} in the example below, but you could use a simpler editor such as {{ic|nano}} if you wish.<br />
<br />
{{hc|vi /etc/locale.gen|<nowiki><br />
...<br />
#en_PH.UTF-8 UTF-8<br />
#en_PH ISO-8859-1<br />
#en_SG.UTF-8 UTF-8<br />
#en_SG ISO-8859-1<br />
#en_US.UTF-8 UTF-8<br />
#en_US ISO-8859-1<br />
#en_ZA.UTF-8 UTF-8<br />
#en_ZA ISO-8859-1<br />
#en_ZM UTF-8<br />
...<br />
</nowiki>}}<br />
<br />
Changing it to (for en_US.UTF-8 as a locale in this example):<br />
<br />
{{bc|<nowiki><br />
...<br />
#en_PH.UTF-8 UTF-8<br />
#en_PH ISO-8859-1<br />
#en_SG.UTF-8 UTF-8<br />
#en_SG ISO-8859-1<br />
en_US.UTF-8 UTF-8<br />
#en_US ISO-8859-1<br />
#en_ZA.UTF-8 UTF-8<br />
#en_ZA ISO-8859-1<br />
#en_ZM UTF-8<br />
...<br />
</nowiki>}}<br />
<br />
Alternately one could simply append a known value to the {{ic|/etc/locale.gen}} file:<br />
<br />
# echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen<br />
<br />
After either method, one runs the {{ic|locale-gen}} command to generate the locale files:<br />
<br />
# locale-gen<br />
<br />
Finally we use {{Man|1|systemd-firstboot}} or {{Man|1|localectl}} to set the system locale. Each of these effectively does the same thing which is to simply write to {{ic|/etc/locale.conf}} (which can simply be edited directly as per standard Arch install instructions).<br />
<br />
==== With systemd-firstboot ====<br />
<br />
{{Man|1|systemd-firstboot}} will prompt us for selection from our generated locales. It will only work if there is no assigned system locale. If you wish to make changes afterward you can use {{Man|1|localectl}}<br />
<br />
# systemd-firstboot --prompt-locale<br />
<br />
==== With localectl ====<br />
<br />
This is an alternate to using {{ic|systemd-firstboot --prompt-locale}}. It may also be used subsequent to that command if further changes to the locale are desired.<br />
<br />
If you need a reminder of which locales have been installed (during this install or later during system changes), use {{ic|localectl list-locales}}:<br />
<br />
{{hc|<nowiki># localectl list-locales</nowiki>|en_US.UTF-8}}<br />
<br />
We then use {{ic|localectl set-locale}}:<br />
<br />
# localectl set-locale LANG=en_US.UTF-8<br />
<br />
=== Time and Date ===<br />
<br />
Unless you have a reason not to, we'll turn on NTP synchronization.<br />
<br />
# timedatectl set-ntp 1<br />
<br />
Then list timezones and pick one<br />
<br />
{{hc|<nowiki># timedatectl list-timezones</nowiki>|<nowiki><br />
...<br />
America/Kentucky/Louisville<br />
America/Kentucky/Monticello<br />
America/Kralendijk<br />
America/La_Paz<br />
America/Lima<br />
America/Los_Angeles<br />
America/Lower_Princes<br />
America/Maceio<br />
America/Managua<br />
America/Manaus<br />
America/Marigot<br />
America/Martinique<br />
America/Matamoros<br />
...<br />
</nowiki>}}<br />
# timedatectl set-timezone America/Los_Angeles<br />
<br />
=== Set hostname ===<br />
<br />
# hostnamectl set-hostname myhostname<br />
<br />
See the man page for {{Man|1|hostnamectl}} for other attributes that can be set. You might also add the hostname to {{Man|5|hosts}}:<br />
<br />
{{hc|/etc/hosts|<br />
127.0.0.1 localhost.localdomain localhost<br />
::1 localhost.localdomain localhost<br />
'''127.0.1.1 ''myhostname''.localdomain ''myhostname'''''<br />
}}<br />
<br />
Use {{ic|echo}} for a scriptable solution:<br />
<br />
# echo "127.0.1.1 myhostname.localdomain myhostname" >> /etc/hosts<br />
<br />
=== Network configuration ===<br />
<br />
Configure the network for the newly installed environment: see [[Network configuration]].<br />
<br />
For [[Wireless configuration]], [[Help:Reading#Installation of packages|install]] the {{Pkg|iw}}, {{Pkg|wpa_supplicant}}, and {{Pkg|dialog}} packages, as well as needed [[Wireless#Installing driver/firmware|firmware packages]].<br />
<br />
=== Base Package Installation ===<br />
<br />
We've already included the {{Grp|base}} group which is, strictly speaking, all you need to boot a minimal Arch Linux system. At this stage, however, we can install some useful utilities (and Xorg or Wayland, etc.).<br />
<br />
# pacman -Syu base-devel btrfs-progs iw gptfdisk zsh vim terminus-font<br />
<br />
=== Initramfs ===<br />
<br />
Creating a new ''initramfs'' is usually not required, because [[mkinitcpio]] was run on installation of the {{Pkg|linux}} package with ''pacstrap''. However we'll need to make some changes to the hooks used on our system. Additionally, I switched over to using the systemd hooks in mkinitcpio, so that is largely what you'll see in my example below.<br />
<br />
I recommend making a backup of your {{ic|/etc/mkinitcpio.conf}} file first:<br />
<br />
# mv /etc/mkinitcpio.conf /etc/mkinitcpio.conf.orig<br />
<br />
and then editing a new file to match the following contents:<br />
<br />
{{bc|<nowiki><br />
MODULES=""<br />
BINARIES=""<br />
FILES=""<br />
HOOKS="base systemd sd-vconsole modconf keyboard block filesystems btrfs sd-encrypt fsck"<br />
</nowiki>}}<br />
<br />
Finally, recreate the initramfs image:<br />
<br />
# mkinitcpio -p linux<br />
<br />
=== Bootloader ===<br />
<br />
{{Warning|THIS SECTION IN PROGRESS}}<br />
<br />
=== Root password ===<br />
<br />
Set the root [[password]]:<br />
<br />
# passwd<br />
<br />
=== Leave the systemd-nspawn environment ===<br />
<br />
Issue a poweroff to exit the nspawned environment:<br />
<br />
# poweroff<br />
<br />
This will return you the Arch installer environment where you can wrap up.<br />
<br />
=== Legacy boot loader ===<br />
<br />
If your system is not UEFI and you need to use a legacy installer like grub, it will need to be installed from within an arch-chroot generated chroot, not the systemd-nspawn running container. An example of this would be (assuming that the drive of the new system is at /dev/sdb):<br />
<br />
# arch-chroot /mnt<br />
# grub-install $DRIVE<br />
# grub-mkconfig -o /boot/grub/grub.cfg<br />
# exit<br />
<br />
== Command Summary ==<br />
<br />
The following are all critical commands (exluded: the initial drive wipe which is optional). It assumes you have successfully brought up networking prior to starting this sequence.<br />
<br />
{{bc|<nowiki><br />
<br />
$DRIVE=/dev/DRIVEID<br />
<br />
sgdisk --zap-all $DRIVE<br />
<br />
sgdisk --clear \<br />
--new=1:0:+550MiB --typecode=1:ef00 --change-name=1:EFI \<br />
--new=2:0:+8GiB --typecode=2:8200 --change-name=2:cryptswap \<br />
--new=3:0:0 --typecode=2:8200 --change-name=3:cryptsystem \<br />
$DRIVE<br />
<br />
mkfs.fat -F32 -n EFI /dev/disk/by-partlabel/EFI<br />
<br />
cryptsetup luksFormat --align-payload=8192 -s 256 -c aes-xts-plain64 /dev/disk/by-partlabel/cryptsystem<br />
<br />
cryptsetup open /dev/disk/by-partlabel/cryptsystem system<br />
<br />
cryptsetup open --type plain --key-file /dev/urandom /dev/disk/by-partlabel/cryptswap swap<br />
<br />
mkswap -L swap /dev/mapper/swap<br />
<br />
swapon -L swap<br />
<br />
mkfs.btrfs --force --label system /dev/mapper/system<br />
<br />
o=defaults,x-mount.mkdir<br />
<br />
o_btrfs=$o,compress=lzo,ssd,noatime<br />
<br />
mount -t btrfs LABEL=system /mnt<br />
<br />
btrfs subvolume create /mnt/root<br />
<br />
btrfs subvolume create /mnt/home<br />
<br />
btrfs subvolume create /mnt/snapshots<br />
<br />
umount -R /mnt<br />
<br />
mount -t btrfs -o subvol=root,$o_btrfs LABEL=system /mnt<br />
<br />
mount -t btrfs -o subvol=home,$o_btrfs LABEL=system /mnt/home<br />
<br />
mount -t btrfs -o subvol=snapshots,$o_btrfs LABEL=system /mnt/.snapshots<br />
<br />
pacstrap /mnt base<br />
<br />
genfstab -L -p /mnt >> /mnt/etc/fstab<br />
<br />
sed -i "s+LABEL=swap+/dev/mapper/swap" /etc/fstab_labels<br />
<br />
systemd-nspawn -bD /mnt<br />
<br />
echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen<br />
<br />
locale-gen<br />
<br />
localectl set-locale LANG=en_US.UTF-8<br />
<br />
timedatectl set-ntp 1<br />
<br />
timedatectl set-timezone America/Los_Angeles<br />
<br />
hostnamectl set-hostname myhostname<br />
<br />
echo "127.0.1.1 myhostname.localdomain myhostname" >> /etc/hosts<br />
<br />
pacman -Syu base-devel btrfs-progs iw gptfdisk zsh vim terminus-font<br />
</nowiki>}}<br />
<br />
== Quick and Dirty ==<br />
<br />
{{Note|an extra example and may be moved to its own wiki page later}}<br />
<br />
This is the approximate process I follow if I want to bring up Arch on, say, an old laptop for a quick purpose built test machine, etc. It's not an install that I consider long term maintainable since rollbacks aren't implemented, nor is there any encryption, but it's a good example of how simple installation can be.<br />
<br />
{{bc|<nowiki><br />
$DRIVE=/dev/DRIVEID<br />
sgdisk --zap-all $DRIVE<br />
mkfs.btrfs -f $DRIVE<br />
mount -t btrfs $DRIVE /mnt<br />
pacstrap /mnt base<br />
systemd-nspawn -bD /mnt<br />
echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen<br />
locale-gen<br />
localectl set-locale LANG=en_US.UTF-8<br />
timedatectl set-ntp 1<br />
timedatectl set-timezone America/Los_Angeles<br />
hostnamectl set-hostname myhostname<br />
poweroff<br />
arch-chroot /mnt<br />
grub-install --root-directory=/mnt $DRIVE<br />
grub-mkconfig -o /mnt/boot/grub/grub.cfg<br />
exit<br />
reboot<br />
</nowiki>}}</div>Altercationhttps://wiki.archlinux.org/index.php?title=User:Altercation/Bullet_Proof_Arch_Install&diff=458656User:Altercation/Bullet Proof Arch Install2016-12-06T18:41:58Z<p>Altercation: /* Create BTRFS Subvolumes */</p>
<hr />
<div>This page is a summary of the current process I follow when installing Arch on a new laptop or desktop. My process varies over time, but this serves as my "state of the art" best practice recommendations. I'm open to feedback and suggestions for improvements.<br />
<br />
{{Note|This is entirely based on my own opinions and research. It is opinionated about the best way to do things given the current state of the kernel, hardware availability, and utilities, filesystems, etc. I will explain my rationale for specific choices and provide links to other sources of information (on the Arch wiki or external) where useful.}}<br />
<br />
== Objectives ==<br />
<br />
The goals of my standard "bullet proof" Arch Linux installation are:<br />
<br />
* Benefit from Arch's rolling release model while mitigating any risk of system corruption or data loss due to failed upgrades<br />
* Minimize risk due to hardware failure or total system loss (e.g. theft or physical destruction)<br />
* Make system rollbacks easy and procedural, using a standard setup and methodology for recovery of previous system (and user data) states<br />
<br />
=== Why not the Arch Install instructions? ===<br />
<br />
The [[Installation guide|Arch Linux installation instructions]] are an excellent, general starting point and you should read and understand them. That being said, they are designed to map to a very, very broad set of installation scenarios. I am interested in a very specific type of installation (daily use desktops and laptops in this article) and I have a strong set of opinions about the "right" or "best practice" way to set up my own working systems.<br />
<br />
These instructions, then, are much more prescriptive and have strong suggestions or directions about how (and why) one should use a particular method during Arch Linux installation.<br />
<br />
=== Key differences from the stock Arch install instructions ===<br />
<br />
How these instructions differ from the standard Arch guidance:<br />
<br />
* We are encrypting the entire system but not using LVM as is often recommended (see the encryption section below for details about why we are not using it).<br />
* I use labels and avoid UUIDs where possible to make switching to an alternate recovery drive easier.<br />
* I skip arch-chroot and simply boot the new system ('''not''' reboot, just boot) from within the install environment using {{Man|1|systemd-nspawn}} which enables the *ctl commands to work (and systemd services to be enabled properly without need for a system reboot)<br />
* I use the various systemd *ctl commands (hostnamectl, timedatectl, localectl, etc.) to configure the system<br />
* I use the systemd mkinitcpio hooks in lieu of the legacy hooks.<br />
* I use BTRFS exclusively for root and home partitions for its backup capabilities.<br />
* I recommend and use secure boot (but not with the Microsoft keys) to minimize risk due to the unavoidably unencrypted EFI partition.<br />
<br />
== Assumptions ==<br />
<br />
These instructions presuppose the following:<br />
<br />
* fairly new hardware (these instructions may work on older hardware, but there may be unusual issues that crop up... if you aren't comfortable handling those situations you should consider a more "traditional" Arch Linux install (e.g. using grub, LVM, ext4, etc.)<br />
* [[Unified Extensible Firmware Interface|UEFI support]] (BIOS system install is also possible with some modification of these instructions, but this has not yet been detailed here)<br />
* probably an [[Solid State Drives|SSD]].<br />
* some familiarity with Arch, or at least some experience with Linux, will help<br />
<br />
{{Warning|I am assuming you are going to single boot (not dual boot) and that you are '''willing to wipe all data from the install drive.''' If that is not the case, do not proceed with these instructions as following them '''will effectively destroy any data (and other operating systems) on the installation target drive.'''}}<br />
<br />
== Prerequisites ==<br />
<br />
You must have a recent copy of the Arch install USB. See [[:Category:Getting and installing Arch]] for general information and [[USB flash installation media]] for specific details on creating a USB Arch installation drive.<br />
<br />
You should also have a reasonable amount of time in which to complete the installation. Novice users will want to budget a couple hours. Experienced users will ''know'' to budget a couple hours.<br />
<br />
== Preparation ==<br />
<br />
=== Boot from USB Drive ===<br />
<br />
Boot your system from your prepared [[USB flash installation media|Arch Linux USB drive]]. It is important that you boot in EFI mode, not legacy BIOS compatibility mode. See the [[Unified Extensible Firmware Interface|UEFI]] article for more information about checking boot mode and ensuring you are booting using EFI.<br />
<br />
=== Bring up the network ===<br />
<br />
If you booted into a system with an ethernet cable plugged in, chances are you're up and running. If you need to use wireless instead, {{ic|wifi-menu}} will more often than not work without trouble. If those don't work, see [[Installation guide#Connect to the Internet|the Arch installation guide section on connecting to the internet]].<br />
<br />
=== Select Drive ===<br />
<br />
I like to use the [[Core utilities#lsblk|{{ic|1=lsblk}}]] command to bring up a quick list of the block devices on the system and identify existing partition structures and sizes, as well as mount points. If you don't already use it, I recommend [[Core utilities#lsblk|{{ic|1=lsblk}}]] when you need information on any given drive or partition. It's useful for polling UUIDs as well. For example, the following command gives you a clearly formatted summary of all block devices, their partition labels, filesystem lables, UUIDs and partition UUIDS: {{ic|lsblk -o +LABEL,PARTLABEL,UUID,PARTUUID}}<br />
<br />
In any case, the plain command without options should be enough to identify the drive you will install to (for example {{ic|1=/dev/sda}} or {{ic|1=/dev/nvme0n1}}:<br />
<br />
# lsblk<br />
<br />
=== Wipe Drive Securely (optional) ===<br />
<br />
While it is not necessary, given that this process will go through the trouble of encrypting the main system partition, it makes sense to do a secure wipe of the drive. This is more or less directly from [[Dm-crypt/Drive preparation#dm-crypt wipe on an empty disk or partition]].<br />
<br />
{{Warning|Be certain of your target device selection as we will be '''wiping this drive''' (either securely or, at minimum, destroying all existing partition data).}}<br />
<br />
First, create a temporary encrypted container the full disk ({{ic|sdX}}) to be encrypted, e.g. using default encryption parameters and a random key via the {{ic|--key-file /dev/{u}random}} option (see also [[Random number generation]]):<br />
<br />
# cryptsetup open --type plain /dev/sdXY container --key-file /dev/urandom<br />
<br />
{{Note|An interesting page addressing myths about /dev/urandom can be [http://www.2uo.de/myths-about-urandom/ found here]}}<br />
<br />
Second, check the container exists:<br />
<br />
{{hc|# fdisk -l|Disk /dev/mapper/container: XXXX MB, XXXXXXXXXX bytes<br />
...<br />
Disk /dev/mapper/container does not contain a valid partition table}}<br />
Wipe the container with zeros. A use of {{ic|1=if=/dev/urandom}} is '''not''' required as the encryption cipher itself generates randomness.<br />
{{hc|# dd <nowiki>if=/dev/zero of=/dev/mapper/container status=progress bs=1M</nowiki>|<br />
dd: writing to ‘/dev/mapper/container’: No space left on device}}<br />
<br />
{{Tip|<br />
* Using ''dd'' with the {{ic|1=bs=}} option, e.g. {{ic|1=bs=1M}} as above, is frequently used to increase disk throughput of the operation.<br />
* To perform a check of the operation, zero the partition before creating the wipe container. After the wipe command {{ic|blockdev --getsize64 ''/dev/mapper/container''}} can be used to get the exact container size as root. Now ''od'' can be used to spotcheck whether the wipe overwrote the zeroed sectors, e.g. {{ic|od -j ''containersize - blocksize''}} to view the wipe completed to the end.}}<br />
<br />
Finally, close the temporary container:<br />
<br />
# cryptsetup close container<br />
<br />
== Partition & Format Drive ==<br />
<br />
=== Understanding some basics about disks, partitions, and filesystems ===<br />
<br />
Think of your drive like a big empty building, no rooms. This is your plain physical drive (either a spinning platter drive or an SSD). Next imagine that to make it useful, we divide the building into apartments. In our analogy the apartments are '''partitions''' of the drive.<br />
<br />
Imagine also that there are a couple different standard methods of creating layout maps to the apartments. These plans are standardized so that the public services that have to access the building regularly (like the fire and police, for example) understand how to find the apartment entrances. In the world of partitioning, the equivalent is the "partition table scheme". The two common schemes are called "MBR" (Master Boot Record, older) and "GPT" (GUID Partition Table, newer). We will be using the new GPT scheme.<br />
<br />
Finally, imagine that the apartments are just empty shells. The act of building walls and laying out the functional structure of the apartments is equivalent to formatting our disk partitions with a filesystem. And just as different layouts may be more or less efficient, or have other different functional characteristics, so to filesystems have different attributes that make them useful in different ways.<br />
<br />
=== Our partition plans ===<br />
<br />
We will take our physical drive and divide it into three partitions. These partitions each serve a distinct purpose. All but the first and smallest, the EFI partition, will be encrypted. For security, if your system supports Secure Boot, you may choose to cryptographically sign the data stored on the EFI partition so that any tampering will be evident, despite the lack of encryption on that partition.<br />
<br />
{{Note|Again, we're assuming an UEFI installation (not legacy BIOS) and a GPT (not MBR) partition structure. If none of that made sense, best to start with the [[Partitioning]] article or do some test installs of Arch first. '''Partitioning is, in my opinion, one of the areas that is most confusing for the new Arch user.''' Additionally, there is a lot "received wisdom" and cargo-cult assumption making about how best to partition. Working through some of the "this is how it's always been done" tutorials isn't necessarily a bad thing... In many cases the way it has always been done has some sound reasoning behind it, despite being cargo-culted half the time. That being said, the method presented here is different from that in most of the Arch wiki partitioning methodologies.}}<br />
<br />
We will not be using LVM. You read a lot about LUKS and LVM and it all gets a bit complicated (LVM on LUKS, LUKS on LVM, etc.). LVM is a "logical volume manager" and abstracts physical devices (drives) into virtual devices, for easier management. It's a good idea but we will be using btrfs to effectively achieve the same results and really don't need the overhead of LVM.<br />
<br />
=== Partition Summary ===<br />
<br />
* 1: EFI - The UEFI 'bios" will look for this FAT32 formatted partition and either locate a default bootloader or will locate a specific EFI boot entry on it. This partition is by necessity not encrypted (unless the drive it is on has been encrypted as a "self encrypting drive")<br />
* 2: Swap - Used by Linux to swap out pages of memory from RAM to disk. Despite debate in this area, it is advisable to have at least some swap space, even it you are not planning on using hibernation on your machine. The Arch wiki is unfortunately rather too brief in its own [[Swap|swap article]] so I recommend the [https://docs.fedoraproject.org/en-US/Fedora/14/html/Storage_Administration_Guide/ch-swapspace.html Fedora documentation on swap] for a good overview on determining the right swap partition size.<br />
* 3: System - This will hold our root and home data. It will be formatted as BTRFS and will use subvolumes to manage snapshots of the current root and home contents.<br />
<br />
=== Visual overview of our partitions, filesystems, and contents ===<br />
<br />
This is a visual summary of our partions (inc. size information), encryption, filesystems, and a summary of the contents of each container.<br />
<br />
{| class="wikitable"<br />
| style="vertical-align: top; padding:1em" | '''Partition 1 (EFI)'''<br />
550MiB+<br />
{| style="border: 1px solid black; background: #DACEF2; margin: 1em;"<br />
! FAT32<br />
|-<br />
|kernel & initramfs<br />
(signed if using secure boot)<br />
|}<br />
| style="vertical-align: top; padding:1em" | '''Partition 2 (Swap)'''<br />
w/ Hibernate: Equal RAM,<br />
w/o Hibernate: min 8GB<br />
{| style="border: 1px solid black; background: #F2ECCE; margin: 1em;"<br />
|-<br />
! dm-crypt<br />
{| style="border: 1px solid black; background: #DACEF2; margin: 1em;"<br />
| SWAP<br />
|}<br />
|}<br />
| style="vertical-align: top; padding:1em" | '''Partition 3 (System)'''<br />
Remaining Space<br />
{| style="border: 1px solid black; background: #F2ECCE; margin: 1em;"<br />
|-<br />
! LUKS dm-crypt<br />
<br />
{| style="border: 1px solid black; background: #DACEF2; margin: 1em;"<br />
| BTRFS Top Level Subvolume<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Root Subvolume<br />
|}<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Home Subvolume<br />
|}<br />
<br />
{| style="border: 1px solid black; background: #E0CEF2; margin: 1em;"<br />
| BTRFS Snapshots Subvolume<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Root Snapshot Subvolume(s)<br />
|}<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Home Snapshot Subvolume(s)<br />
|}<br />
<br />
|}<br />
<br />
|}<br />
<br />
|}<br />
<br />
|}<br />
<br />
=== Partition Drive ===<br />
<br />
There are many utilities available for [[Partitioning]]. Because we are using Arch Linux and the command line doesn't hurt us (it makes us stronger) we will be using pure, non-interactive command line tools for this. Specifically, we will be using the utility [[Fdisk#Using_sgdisk|sgdisk]] from the {{Pkg|gptfdisk}} package. The [[Fdisk|fdisk]] utility now also supports GPT partitioned drives, so it would be an alternative. [[Fdisk#Using_sgdisk|sgdisk]] is available by default on the standard Arch install iso that you use to make your bootable USB drive.<br />
<br />
First, select the drive you will install to. Make sure you have selected the correct drive!. Again, a quick {{ic|lsblk}} will work here.<br />
<br />
# $DRIVE=/dev/DRIVEID<br />
<br />
(replace /dev/DRIVEID with the correct value, for example /dev/sda, /dev/nvme0n1, etc.)<br />
<br />
If you didn't securely wipe the drive already, it's worth "zapping" it using [[Fdisk#Using_sgdisk|sgdisk]] to remove any lingering legacy partition information. If you already wiped the drive you can skip this command (though it won't hurt to run it again).<br />
<br />
{{Warning|'''This command will also effectively erase the selected drive!'''}}<br />
<br />
# sgdisk --zap-all $DRIVE<br />
<br />
The following command will then create all three partitions in one go. '''It will also effectively erase the selected drive!'''<br />
<br />
# sgdisk --clear \<br />
--new=1:0:+550MiB --typecode=1:ef00 --change-name=1:EFI \<br />
--new=2:0:+8GiB --typecode=2:8200 --change-name=2:cryptswap \<br />
--new=3:0:0 --typecode=2:8200 --change-name=3:cryptsystem \<br />
$DRIVE<br />
<br />
It is worth noting that the "--change-name" values are, in this case, creating GPT "partition labels". You can subsequently see these by using the {{ic|lsblk -o +PARTLABEL}} command. It is good to use "EFI" for the efi partition. I am not aware of UEFI implementations that actively use the label for identification of the EFI partition, but it is possible that some do (UEFI bios implementations are not always consistent or to spec). The other two names are entirely "arbitrary". There is nothing special about calling them cryptswap and cryptsystem; they are simply good, clear names that remind us of the purpose of this partition and what it contains (for example, "cryptswap" suggests "this partition is for swap, and is encrypted").<br />
<br />
One final note about partition labels: we want them to be unique on your system. If for some reason there is already a GPT partition with the name EFI on another drive on your system, either change that partition name or use something besides "EFI" to avoid a namespace collision.<br />
<br />
Note also, that the backslashes at the end of each line can be omitted if you are writing the command on one long line instead. Those simply allow the splitting of a single command onto multiple lines.<br />
<br />
=== Format EFI Partition ===<br />
<br />
Next up: format the first (EFI) partition using the (required) FAT32 filesystem.<br />
<br />
# mkfs.fat -F32 -n EFI /dev/disk/by-partlabel/EFI<br />
<br />
Note that we here make use of the partition label we just assigned. I prefer doing this since it simplifies scripts significantly for me and makes them, in my opinion, more readable.<br />
<br />
=== Encrypt System Partition ===<br />
<br />
Encrypt the main partition. Use a good passphrase. Note that the "--align-payload" value has been used as per [http://www.spinics.net/lists/dm-crypt/msg02421.html this suggestion/explanation] on the dm-crypt mailing list.<br />
<br />
Note also that I selected the encryption algorithm and key size using cryptsetup benchmark. See the [[Dm-crypt/Device_encryption]] article for more details.<br />
<br />
# cryptsetup luksFormat --align-payload=8192 -s 256 -c aes-xts-plain64 /dev/disk/by-partlabel/cryptsystem<br />
<br />
After creating the encrypted container, open it. Again, note the use of the partition label to identify the drive. Additionally, note that once we open this device we are giving it a name of "system." Thus "cryptsystem" is the encrypted system partition, while "system" is the name we are using once it has been opened in an unencrypted state. These names are arbitrary (Linux doesn't care what we use) but they help us keep things organized during this process.<br />
<br />
# cryptsetup open /dev/disk/by-partlabel/cryptsystem system<br />
<br />
=== Bring Up Encrypted Swap ===<br />
<br />
Finally we create encrypted swap. In this example we are not enabling hibernation. I will provide information on how to enable hibernation separately. Again, using partition labels to identify the partition and going from "cryptswap" to just "swap".<br />
<br />
We are not using LUKS here (which effectively makes dm-crypt easier to use). We're just using plain dm-crypt to encrypt the swap partition using a random key.<br />
<br />
# cryptsetup open --type plain --key-file /dev/urandom /dev/disk/by-partlabel/cryptswap swap<br />
# mkswap -L swap /dev/mapper/swap<br />
# swapon -L swap<br />
<br />
=== Create and mount BTRFS subvolumes ===<br />
<br />
Now on to the main attraction: creating our BTRFS subvolume structure. While BTRFS can be set up like any other filesystem (single command, just use the created file system directly), we're going to use the power of BTRFS to enable snapshotting our system state efficiently and rollbacks as necessary.<br />
<br />
First we create a top-level BTRFS subvolume. Note that the top-level entity in BTRFS nomenclature is still referred to as a '''sub'''volume, despite being at the top-level.<br />
<br />
We will create and mount this subvolume, create some new subvolumes inside it, and then switch to those subvolumes as our proper, mounted filesystems. Doing this will enable us to treat our root filesystem as a snapshotable object.<br />
<br />
Top-level subvolume creation.<br />
<br />
# mkfs.btrfs --force --label system /dev/mapper/system<br />
<br />
Temporarily mount our top-level volume for further subvolume creation. Note that the variable 'o' in this case is our default set of options for any given filesystem mount, while "o_btrfs" are those plus some options specific to btrfs. The default option "x-mount.mkdir" is a neat trick that allows us to skip the creation of directories for mountpoints (they will be created automatically). We assume /mnt as the standard mount point, as in a normal Arch Linux installation.<br />
<br />
# o=defaults,x-mount.mkdir<br />
# o_btrfs=$o,compress=lzo,ssd,noatime<br />
<br />
Note the use of our filesystem label to mount our subvolume. This is distinct from the partition labels used earlier. See the Arch wiki article on [[Persistent_block_device_naming]] for more information.<br />
<br />
# mount -t btrfs LABEL=system /mnt<br />
<br />
Now we create the subvolumes which will actually be mounted in our running system:<br />
<br />
# btrfs subvolume create /mnt/root<br />
# btrfs subvolume create /mnt/home<br />
# btrfs subvolume create /mnt/snapshots<br />
<br />
Then we unmount everything...<br />
<br />
# umount -R /mnt<br />
<br />
And remount just the subvolumes under our top-level subvolume (which remains unmounted unless we need to do "surgery" and rollback to a previous system system):<br />
<br />
# mount -t btrfs -o subvol=root,$o_btrfs LABEL=system /mnt<br />
<br />
Before mounting the home and snapshots subvolumes, let's walk through that command so we understand what it's doing:<br />
<br />
The 'mount -t btrfs' just specifies that our filesystem is of type BTRFS. This is often not necessary since mount will attempt to identify the filesystem type, but being explicit is often the best strategy with command line utilities, so we identify the type here.<br />
<br />
We use our previously defined mount options with the $o_btrfs variable and add the additional option "subvol=root" (separating it from our other defaults with a comma, of course). The next part of the command is "LABEL=system". Combined this reads as "mount the filesystem with the 'system' label, and use the 'root' subvolume within that".<br />
<br />
Finally, all this gets mounted at our install root, which in this case is "/mnt".<br />
<br />
Now let's pick back up and mount our home and snapshots subvolumes. Note that while the subvolume name is "snapshots", we will mount it at ".snapshots" (note dot prefix for the mount point). This will keep our root directory listing clean but will still make it available at a reasonable mount location.<br />
<br />
# mount -t btrfs -o subvol=home,$o_btrfs LABEL=system /mnt/home<br />
# mount -t btrfs -o subvol=snapshots,$o_btrfs LABEL=system /mnt/.snapshots<br />
<br />
It it worth noting that in each case we are telling mount to use the same filesystem, namely the one labeled "system". However in each case we are also telling it to look for a different subvolume in that filesystem (via the "subvol=" option).<br />
<br />
With this done, we can move on to installing the actual system.<br />
<br />
== Installation of Base Arch Linux System ==<br />
<br />
We are currently running off the Arch installer root filesystem. We will first use the 'pacstrap' utility to start our installation and then we will boot into our new minimal system using systemd-nspawn.<br />
<br />
=== Install base package group ===<br />
<br />
# pacstrap /mnt base<br />
<br />
=== fstab Generation and Modification ===<br />
<br />
{{Note|In a simpler, non encrypted configuration it is possible to skip making an fstab altogether due to a standard known as the [https://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/ Discoverable Partitions Spec]. However given the complexity of our encrypted, btrfs subvolume configuration, we require an fstab at this time. It is possible that in future we might feasibly do away with the fstab almost entirely in this setup (see the [https://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/#whataboutautomaticmountingofbtrfssubvolumestovarhomeandsoon 'What about automatic mounting of btrfs subvolumes'] section on that page).}}<br />
<br />
Create an [[fstab]] filesystem table file, using labels (-L) to identify the filesystems.<br />
<br />
# genfstab -L -p /mnt >> /mnt/etc/fstab<br />
<br />
I prefer to use labels as this makes the system more portable to a backup drive. You should end up with something that looks pretty close to this:<br />
<br />
{{hc|# cat /mnt/etc/fstab|<nowiki><br />
# /dev/mapper/system UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=system / btrfs rw,noatime,compress=lzo,ssd,space_cache,subvolid=257,subvol=/root,subvol=root 0 0<br />
<br />
# /dev/mapper/system UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=system /home btrfs rw,noatime,compress=lzo,ssd,space_cache,subvolid=258,subvol=/home,subvol=home 0 0<br />
<br />
# /dev/mapper/system UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=system /.snapshots btrfs rw,noatime,compress=lzo,ssd,space_cache,subvolid=259,subvol=/snapshots,subvol=snapshots 0 0<br />
<br />
# /dev/nvme0n1p1 UUID=xxxx-xxxx<br />
LABEL=EFI /boot/EFI vfat rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro 0 2<br />
<br />
# /dev/mapper/swap UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=swap none swap defaults 0 0<br />
</nowiki>}}<br />
<br />
There is one problem, however. Swap will not remount this way (the plain dm-crypt partition with a random key will not have a label when it is recreated on reboot). You will have to change that line from this:<br />
<br />
{{bc|<nowiki>LABEL=swap none swap defaults 0 0</nowiki>}}<br />
<br />
to this:<br />
<br />
{{bc|/dev/mapper/swap none swap defaults 0 0}}<br />
<br />
This will ensure that the mapped device is opened as swap successfully. The other lines may remain unchanged.<br />
<br />
==== Use {{ic|sed}} instead ====<br />
<br />
As a (scriptable) alternative to the manual editing of your {{ic|/etc/fstab}} you could use {{Man|1|sed}} to edit the file in place:<br />
<br />
# sed -i s+LABEL=swap+/dev/mapper/swap+ /mnt/etc/fstab_labels<br />
<br />
=== Boot into new system ===<br />
<br />
{{Warning|While this works, I am fairly certain I'll want to double check some things before declaring this step final. Specifically I want to consider some bind mounts and whether there is anything that should be r/w instead of r/o as is normal in a systemd-nspawn container.}}<br />
<br />
# systemd-nspawn -bD /mnt<br />
<br />
This will boot your new base Arch Linux system. After the standard boot messages scroll by you will be presented with a login (enter {{ic|root}} and hit enter to login).<br />
<br />
=== Generate and set locale ===<br />
<br />
Next, edit and uncomment your desired locale(s) from {{ic|/etc/locale.gen}}. We use {{ic|vi}} in the example below, but you could use a simpler editor such as {{ic|nano}} if you wish.<br />
<br />
{{hc|vi /etc/locale.gen|<nowiki><br />
...<br />
#en_PH.UTF-8 UTF-8<br />
#en_PH ISO-8859-1<br />
#en_SG.UTF-8 UTF-8<br />
#en_SG ISO-8859-1<br />
#en_US.UTF-8 UTF-8<br />
#en_US ISO-8859-1<br />
#en_ZA.UTF-8 UTF-8<br />
#en_ZA ISO-8859-1<br />
#en_ZM UTF-8<br />
...<br />
</nowiki>}}<br />
<br />
Changing it to (for en_US.UTF-8 as a locale in this example):<br />
<br />
{{bc|<nowiki><br />
...<br />
#en_PH.UTF-8 UTF-8<br />
#en_PH ISO-8859-1<br />
#en_SG.UTF-8 UTF-8<br />
#en_SG ISO-8859-1<br />
en_US.UTF-8 UTF-8<br />
#en_US ISO-8859-1<br />
#en_ZA.UTF-8 UTF-8<br />
#en_ZA ISO-8859-1<br />
#en_ZM UTF-8<br />
...<br />
</nowiki>}}<br />
<br />
Alternately one could simply append a known value to the {{ic|/etc/locale.gen}} file:<br />
<br />
# echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen<br />
<br />
After either method, one runs the {{ic|locale-gen}} command to generate the locale files:<br />
<br />
# locale-gen<br />
<br />
Finally we use {{Man|1|systemd-firstboot}} or {{Man|1|localectl}} to set the system locale. Each of these effectively does the same thing which is to simply write to {{ic|/etc/locale.conf}} (which can simply be edited directly as per standard Arch install instructions).<br />
<br />
==== With systemd-firstboot ====<br />
<br />
{{Man|1|systemd-firstboot}} will prompt us for selection from our generated locales. It will only work if there is no assigned system locale. If you wish to make changes afterward you can use {{Man|1|localectl}}<br />
<br />
# systemd-firstboot --prompt-locale<br />
<br />
==== With localectl ====<br />
<br />
This is an alternate to using {{ic|systemd-firstboot --prompt-locale}}. It may also be used subsequent to that command if further changes to the locale are desired.<br />
<br />
If you need a reminder of which locales have been installed (during this install or later during system changes), use {{ic|localectl list-locales}}:<br />
<br />
{{hc|<nowiki># localectl list-locales</nowiki>|en_US.UTF-8}}<br />
<br />
We then use {{ic|localectl set-locale}}:<br />
<br />
# localectl set-locale LANG=en_US.UTF-8<br />
<br />
=== Time and Date ===<br />
<br />
Unless you have a reason not to, we'll turn on NTP synchronization.<br />
<br />
# timedatectl set-ntp 1<br />
<br />
Then list timezones and pick one<br />
<br />
{{hc|<nowiki># timedatectl list-timezones</nowiki>|<nowiki><br />
...<br />
America/Kentucky/Louisville<br />
America/Kentucky/Monticello<br />
America/Kralendijk<br />
America/La_Paz<br />
America/Lima<br />
America/Los_Angeles<br />
America/Lower_Princes<br />
America/Maceio<br />
America/Managua<br />
America/Manaus<br />
America/Marigot<br />
America/Martinique<br />
America/Matamoros<br />
...<br />
</nowiki>}}<br />
# timedatectl set-timezone America/Los_Angeles<br />
<br />
=== Set hostname ===<br />
<br />
# hostnamectl set-hostname myhostname<br />
<br />
See the man page for {{Man|1|hostnamectl}} for other attributes that can be set. You might also add the hostname to {{Man|5|hosts}}:<br />
<br />
{{hc|/etc/hosts|<br />
127.0.0.1 localhost.localdomain localhost<br />
::1 localhost.localdomain localhost<br />
'''127.0.1.1 ''myhostname''.localdomain ''myhostname'''''<br />
}}<br />
<br />
Use {{ic|echo}} for a scriptable solution:<br />
<br />
# echo "127.0.1.1 myhostname.localdomain myhostname" >> /etc/hosts<br />
<br />
=== Network configuration ===<br />
<br />
Configure the network for the newly installed environment: see [[Network configuration]].<br />
<br />
For [[Wireless configuration]], [[Help:Reading#Installation of packages|install]] the {{Pkg|iw}}, {{Pkg|wpa_supplicant}}, and {{Pkg|dialog}} packages, as well as needed [[Wireless#Installing driver/firmware|firmware packages]].<br />
<br />
=== Base Package Installation ===<br />
<br />
We've already included the {{Grp|base}} group which is, strictly speaking, all you need to boot a minimal Arch Linux system. At this stage, however, we can install some useful utilities (and Xorg or Wayland, etc.).<br />
<br />
# pacman -Syu base-devel btrfs-progs iw gptfdisk zsh vim terminus-font<br />
<br />
=== Initramfs ===<br />
<br />
Creating a new ''initramfs'' is usually not required, because [[mkinitcpio]] was run on installation of the {{Pkg|linux}} package with ''pacstrap''. However we'll need to make some changes to the hooks used on our system. Additionally, I switched over to using the systemd hooks in mkinitcpio, so that is largely what you'll see in my example below.<br />
<br />
I recommend making a backup of your {{ic|/etc/mkinitcpio.conf}} file first:<br />
<br />
# mv /etc/mkinitcpio.conf /etc/mkinitcpio.conf.orig<br />
<br />
and then editing a new file to match the following contents:<br />
<br />
{{bc|<nowiki><br />
MODULES=""<br />
BINARIES=""<br />
FILES=""<br />
HOOKS="base systemd sd-vconsole modconf keyboard block filesystems btrfs sd-encrypt fsck"<br />
</nowiki>}}<br />
<br />
Finally, recreate the initramfs image:<br />
<br />
# mkinitcpio -p linux<br />
<br />
=== Bootloader ===<br />
<br />
{{Warning|THIS SECTION IN PROGRESS}}<br />
<br />
=== Root password ===<br />
<br />
Set the root [[password]]:<br />
<br />
# passwd<br />
<br />
=== Leave the systemd-nspawn environment ===<br />
<br />
Issue a poweroff to exit the nspawned environment:<br />
<br />
# poweroff<br />
<br />
This will return you the Arch installer environment where you can wrap up.<br />
<br />
=== Legacy boot loader ===<br />
<br />
If your system is not UEFI and you need to use a legacy installer like grub, it will need to be installed from within an arch-chroot generated chroot, not the systemd-nspawn running container. An example of this would be (assuming that the drive of the new system is at /dev/sdb):<br />
<br />
# arch-chroot /mnt<br />
# grub-install $DRIVE<br />
# grub-mkconfig -o /boot/grub/grub.cfg<br />
# exit<br />
<br />
== Command Summary ==<br />
<br />
The following are all critical commands (exluded: the initial drive wipe which is optional). It assumes you have successfully brought up networking prior to starting this sequence.<br />
<br />
{{bc|<nowiki><br />
<br />
$DRIVE=/dev/DRIVEID<br />
<br />
sgdisk --zap-all $DRIVE<br />
<br />
sgdisk --clear \<br />
--new=1:0:+550MiB --typecode=1:ef00 --change-name=1:EFI \<br />
--new=2:0:+8GiB --typecode=2:8200 --change-name=2:cryptswap \<br />
--new=3:0:0 --typecode=2:8200 --change-name=3:cryptsystem \<br />
$DRIVE<br />
<br />
mkfs.fat -F32 -n EFI /dev/disk/by-partlabel/EFI<br />
<br />
cryptsetup luksFormat --align-payload=8192 -s 256 -c aes-xts-plain64 /dev/disk/by-partlabel/cryptsystem<br />
<br />
cryptsetup open /dev/disk/by-partlabel/cryptsystem system<br />
<br />
cryptsetup open --type plain --key-file /dev/urandom /dev/disk/by-partlabel/cryptswap swap<br />
<br />
mkswap -L swap /dev/mapper/swap<br />
<br />
swapon -L swap<br />
<br />
mkfs.btrfs --force --label system /dev/mapper/system<br />
<br />
o=defaults,x-mount.mkdir<br />
<br />
o_btrfs=$o,compress=lzo,ssd,noatime<br />
<br />
mount -t btrfs LABEL=system /mnt<br />
<br />
btrfs subvolume create /mnt/root<br />
<br />
btrfs subvolume create /mnt/home<br />
<br />
btrfs subvolume create /mnt/snapshots<br />
<br />
umount -R /mnt<br />
<br />
mount -t btrfs -o subvol=root,$o_btrfs LABEL=system /mnt<br />
<br />
mount -t btrfs -o subvol=home,$o_btrfs LABEL=system /mnt/home<br />
<br />
mount -t btrfs -o subvol=snapshots,$o_btrfs LABEL=system /mnt/.snapshots<br />
<br />
pacstrap /mnt base<br />
<br />
genfstab -L -p /mnt >> /mnt/etc/fstab<br />
<br />
sed -i "s+LABEL=swap+/dev/mapper/swap" /etc/fstab_labels<br />
<br />
systemd-nspawn -bD /mnt<br />
<br />
echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen<br />
<br />
locale-gen<br />
<br />
localectl set-locale LANG=en_US.UTF-8<br />
<br />
timedatectl set-ntp 1<br />
<br />
timedatectl set-timezone America/Los_Angeles<br />
<br />
hostnamectl set-hostname myhostname<br />
<br />
echo "127.0.1.1 myhostname.localdomain myhostname" >> /etc/hosts<br />
<br />
pacman -Syu base-devel btrfs-progs iw gptfdisk zsh vim terminus-font<br />
</nowiki>}}<br />
<br />
== Quick and Dirty ==<br />
<br />
{{Note|an extra example and may be moved to its own wiki page later}}<br />
<br />
This is the approximate process I follow if I want to bring up Arch on, say, an old laptop for a quick purpose built test machine, etc. It's not an install that I consider long term maintainable since rollbacks aren't implemented, nor is there any encryption, but it's a good example of how simple installation can be.<br />
<br />
{{bc|<nowiki><br />
$DRIVE=/dev/DRIVEID<br />
sgdisk --zap-all $DRIVE<br />
mkfs.btrfs -f $DRIVE<br />
mount -t btrfs $DRIVE /mnt<br />
pacstrap /mnt base<br />
systemd-nspawn -bD /mnt<br />
echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen<br />
locale-gen<br />
localectl set-locale LANG=en_US.UTF-8<br />
timedatectl set-ntp 1<br />
timedatectl set-timezone America/Los_Angeles<br />
hostnamectl set-hostname myhostname<br />
poweroff<br />
arch-chroot /mnt<br />
grub-install --root-directory=/mnt $DRIVE<br />
grub-mkconfig -o /mnt/boot/grub/grub.cfg<br />
exit<br />
reboot<br />
</nowiki>}}</div>Altercationhttps://wiki.archlinux.org/index.php?title=User:Altercation/Bullet_Proof_Arch_Install&diff=458645User:Altercation/Bullet Proof Arch Install2016-12-06T17:52:01Z<p>Altercation: /* Use {{ic|sed}} instead */</p>
<hr />
<div>This page is a summary of the current process I follow when installing Arch on a new laptop or desktop. My process varies over time, but this serves as my "state of the art" best practice recommendations. I'm open to feedback and suggestions for improvements.<br />
<br />
{{Note|This is entirely based on my own opinions and research. It is opinionated about the best way to do things given the current state of the kernel, hardware availability, and utilities, filesystems, etc. I will explain my rationale for specific choices and provide links to other sources of information (on the Arch wiki or external) where useful.}}<br />
<br />
== Objectives ==<br />
<br />
The goals of my standard "bullet proof" Arch Linux installation are:<br />
<br />
* Benefit from Arch's rolling release model while mitigating any risk of system corruption or data loss due to failed upgrades<br />
* Minimize risk due to hardware failure or total system loss (e.g. theft or physical destruction)<br />
* Make system rollbacks easy and procedural, using a standard setup and methodology for recovery of previous system (and user data) states<br />
<br />
=== Why not the Arch Install instructions? ===<br />
<br />
The [[Installation guide|Arch Linux installation instructions]] are an excellent, general starting point and you should read and understand them. That being said, they are designed to map to a very, very broad set of installation scenarios. I am interested in a very specific type of installation (daily use desktops and laptops in this article) and I have a strong set of opinions about the "right" or "best practice" way to set up my own working systems.<br />
<br />
These instructions, then, are much more prescriptive and have strong suggestions or directions about how (and why) one should use a particular method during Arch Linux installation.<br />
<br />
=== Key differences from the stock Arch install instructions ===<br />
<br />
How these instructions differ from the standard Arch guidance:<br />
<br />
* We are encrypting the entire system but not using LVM as is often recommended (see the encryption section below for details about why we are not using it).<br />
* I use labels and avoid UUIDs where possible to make switching to an alternate recovery drive easier.<br />
* I skip arch-chroot and simply boot the new system ('''not''' reboot, just boot) from within the install environment using {{Man|1|systemd-nspawn}} which enables the *ctl commands to work (and systemd services to be enabled properly without need for a system reboot)<br />
* I use the various systemd *ctl commands (hostnamectl, timedatectl, localectl, etc.) to configure the system<br />
* I use the systemd mkinitcpio hooks in lieu of the legacy hooks.<br />
* I use BTRFS exclusively for root and home partitions for its backup capabilities.<br />
* I recommend and use secure boot (but not with the Microsoft keys) to minimize risk due to the unavoidably unencrypted EFI partition.<br />
<br />
== Assumptions ==<br />
<br />
These instructions presuppose the following:<br />
<br />
* fairly new hardware (these instructions may work on older hardware, but there may be unusual issues that crop up... if you aren't comfortable handling those situations you should consider a more "traditional" Arch Linux install (e.g. using grub, LVM, ext4, etc.)<br />
* [[Unified Extensible Firmware Interface|UEFI support]] (BIOS system install is also possible with some modification of these instructions, but this has not yet been detailed here)<br />
* probably an [[Solid State Drives|SSD]].<br />
* some familiarity with Arch, or at least some experience with Linux, will help<br />
<br />
{{Warning|I am assuming you are going to single boot (not dual boot) and that you are '''willing to wipe all data from the install drive.''' If that is not the case, do not proceed with these instructions as following them '''will effectively destroy any data (and other operating systems) on the installation target drive.'''}}<br />
<br />
== Prerequisites ==<br />
<br />
You must have a recent copy of the Arch install USB. See [[:Category:Getting and installing Arch]] for general information and [[USB flash installation media]] for specific details on creating a USB Arch installation drive.<br />
<br />
You should also have a reasonable amount of time in which to complete the installation. Novice users will want to budget a couple hours. Experienced users will ''know'' to budget a couple hours.<br />
<br />
== Preparation ==<br />
<br />
=== Boot from USB Drive ===<br />
<br />
Boot your system from your prepared [[USB flash installation media|Arch Linux USB drive]]. It is important that you boot in EFI mode, not legacy BIOS compatibility mode. See the [[Unified Extensible Firmware Interface|UEFI]] article for more information about checking boot mode and ensuring you are booting using EFI.<br />
<br />
=== Bring up the network ===<br />
<br />
If you booted into a system with an ethernet cable plugged in, chances are you're up and running. If you need to use wireless instead, {{ic|wifi-menu}} will more often than not work without trouble. If those don't work, see [[Installation guide#Connect to the Internet|the Arch installation guide section on connecting to the internet]].<br />
<br />
=== Select Drive ===<br />
<br />
I like to use the [[Core utilities#lsblk|{{ic|1=lsblk}}]] command to bring up a quick list of the block devices on the system and identify existing partition structures and sizes, as well as mount points. If you don't already use it, I recommend [[Core utilities#lsblk|{{ic|1=lsblk}}]] when you need information on any given drive or partition. It's useful for polling UUIDs as well. For example, the following command gives you a clearly formatted summary of all block devices, their partition labels, filesystem lables, UUIDs and partition UUIDS: {{ic|lsblk -o +LABEL,PARTLABEL,UUID,PARTUUID}}<br />
<br />
In any case, the plain command without options should be enough to identify the drive you will install to (for example {{ic|1=/dev/sda}} or {{ic|1=/dev/nvme0n1}}:<br />
<br />
# lsblk<br />
<br />
=== Wipe Drive Securely (optional) ===<br />
<br />
While it is not necessary, given that this process will go through the trouble of encrypting the main system partition, it makes sense to do a secure wipe of the drive. This is more or less directly from [[Dm-crypt/Drive preparation#dm-crypt wipe on an empty disk or partition]].<br />
<br />
{{Warning|Be certain of your target device selection as we will be '''wiping this drive''' (either securely or, at minimum, destroying all existing partition data).}}<br />
<br />
First, create a temporary encrypted container the full disk ({{ic|sdX}}) to be encrypted, e.g. using default encryption parameters and a random key via the {{ic|--key-file /dev/{u}random}} option (see also [[Random number generation]]):<br />
<br />
# cryptsetup open --type plain /dev/sdXY container --key-file /dev/urandom<br />
<br />
{{Note|An interesting page addressing myths about /dev/urandom can be [http://www.2uo.de/myths-about-urandom/ found here]}}<br />
<br />
Second, check the container exists:<br />
<br />
{{hc|# fdisk -l|Disk /dev/mapper/container: XXXX MB, XXXXXXXXXX bytes<br />
...<br />
Disk /dev/mapper/container does not contain a valid partition table}}<br />
Wipe the container with zeros. A use of {{ic|1=if=/dev/urandom}} is '''not''' required as the encryption cipher itself generates randomness.<br />
{{hc|# dd <nowiki>if=/dev/zero of=/dev/mapper/container status=progress bs=1M</nowiki>|<br />
dd: writing to ‘/dev/mapper/container’: No space left on device}}<br />
<br />
{{Tip|<br />
* Using ''dd'' with the {{ic|1=bs=}} option, e.g. {{ic|1=bs=1M}} as above, is frequently used to increase disk throughput of the operation.<br />
* To perform a check of the operation, zero the partition before creating the wipe container. After the wipe command {{ic|blockdev --getsize64 ''/dev/mapper/container''}} can be used to get the exact container size as root. Now ''od'' can be used to spotcheck whether the wipe overwrote the zeroed sectors, e.g. {{ic|od -j ''containersize - blocksize''}} to view the wipe completed to the end.}}<br />
<br />
Finally, close the temporary container:<br />
<br />
# cryptsetup close container<br />
<br />
== Partition & Format Drive ==<br />
<br />
=== Understanding some basics about disks, partitions, and filesystems ===<br />
<br />
Think of your drive like a big empty building, no rooms. This is your plain physical drive (either a spinning platter drive or an SSD). Next imagine that to make it useful, we divide the building into apartments. In our analogy the apartments are '''partitions''' of the drive.<br />
<br />
Imagine also that there are a couple different standard methods of creating layout maps to the apartments. These plans are standardized so that the public services that have to access the building regularly (like the fire and police, for example) understand how to find the apartment entrances. In the world of partitioning, the equivalent is the "partition table scheme". The two common schemes are called "MBR" (Master Boot Record, older) and "GPT" (GUID Partition Table, newer). We will be using the new GPT scheme.<br />
<br />
Finally, imagine that the apartments are just empty shells. The act of building walls and laying out the functional structure of the apartments is equivalent to formatting our disk partitions with a filesystem. And just as different layouts may be more or less efficient, or have other different functional characteristics, so to filesystems have different attributes that make them useful in different ways.<br />
<br />
=== Our partition plans ===<br />
<br />
We will take our physical drive and divide it into three partitions. These partitions each serve a distinct purpose. All but the first and smallest, the EFI partition, will be encrypted. For security, if your system supports Secure Boot, you may choose to cryptographically sign the data stored on the EFI partition so that any tampering will be evident, despite the lack of encryption on that partition.<br />
<br />
{{Note|Again, we're assuming an UEFI installation (not legacy BIOS) and a GPT (not MBR) partition structure. If none of that made sense, best to start with the [[Partitioning]] article or do some test installs of Arch first. '''Partitioning is, in my opinion, one of the areas that is most confusing for the new Arch user.''' Additionally, there is a lot "received wisdom" and cargo-cult assumption making about how best to partition. Working through some of the "this is how it's always been done" tutorials isn't necessarily a bad thing... In many cases the way it has always been done has some sound reasoning behind it, despite being cargo-culted half the time. That being said, the method presented here is different from that in most of the Arch wiki partitioning methodologies.}}<br />
<br />
We will not be using LVM. You read a lot about LUKS and LVM and it all gets a bit complicated (LVM on LUKS, LUKS on LVM, etc.). LVM is a "logical volume manager" and abstracts physical devices (drives) into virtual devices, for easier management. It's a good idea but we will be using btrfs to effectively achieve the same results and really don't need the overhead of LVM.<br />
<br />
=== Partition Summary ===<br />
<br />
* 1: EFI - The UEFI 'bios" will look for this FAT32 formatted partition and either locate a default bootloader or will locate a specific EFI boot entry on it. This partition is by necessity not encrypted (unless the drive it is on has been encrypted as a "self encrypting drive")<br />
* 2: Swap - Used by Linux to swap out pages of memory from RAM to disk. Despite debate in this area, it is advisable to have at least some swap space, even it you are not planning on using hibernation on your machine. The Arch wiki is unfortunately rather too brief in its own [[Swap|swap article]] so I recommend the [https://docs.fedoraproject.org/en-US/Fedora/14/html/Storage_Administration_Guide/ch-swapspace.html Fedora documentation on swap] for a good overview on determining the right swap partition size.<br />
* 3: System - This will hold our root and home data. It will be formatted as BTRFS and will use subvolumes to manage snapshots of the current root and home contents.<br />
<br />
=== Visual overview of our partitions, filesystems, and contents ===<br />
<br />
This is a visual summary of our partions (inc. size information), encryption, filesystems, and a summary of the contents of each container.<br />
<br />
{| class="wikitable"<br />
| style="vertical-align: top; padding:1em" | '''Partition 1 (EFI)'''<br />
550MiB+<br />
{| style="border: 1px solid black; background: #DACEF2; margin: 1em;"<br />
! FAT32<br />
|-<br />
|kernel & initramfs<br />
(signed if using secure boot)<br />
|}<br />
| style="vertical-align: top; padding:1em" | '''Partition 2 (Swap)'''<br />
w/ Hibernate: Equal RAM,<br />
w/o Hibernate: min 8GB<br />
{| style="border: 1px solid black; background: #F2ECCE; margin: 1em;"<br />
|-<br />
! dm-crypt<br />
{| style="border: 1px solid black; background: #DACEF2; margin: 1em;"<br />
| SWAP<br />
|}<br />
|}<br />
| style="vertical-align: top; padding:1em" | '''Partition 3 (System)'''<br />
Remaining Space<br />
{| style="border: 1px solid black; background: #F2ECCE; margin: 1em;"<br />
|-<br />
! LUKS dm-crypt<br />
<br />
{| style="border: 1px solid black; background: #DACEF2; margin: 1em;"<br />
| BTRFS Top Level Subvolume<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Root Subvolume<br />
|}<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Home Subvolume<br />
|}<br />
<br />
{| style="border: 1px solid black; background: #E0CEF2; margin: 1em;"<br />
| BTRFS Snapshots Subvolume<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Root Snapshot Subvolume(s)<br />
|}<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Home Snapshot Subvolume(s)<br />
|}<br />
<br />
|}<br />
<br />
|}<br />
<br />
|}<br />
<br />
|}<br />
<br />
=== Partition Drive ===<br />
<br />
There are many utilities available for [[Partitioning]]. Because we are using Arch Linux and the command line doesn't hurt us (it makes us stronger) we will be using pure, non-interactive command line tools for this. Specifically, we will be using the utility [[Fdisk#Using_sgdisk|sgdisk]] from the {{Pkg|gptfdisk}} package. The [[Fdisk|fdisk]] utility now also supports GPT partitioned drives, so it would be an alternative. [[Fdisk#Using_sgdisk|sgdisk]] is available by default on the standard Arch install iso that you use to make your bootable USB drive.<br />
<br />
First, select the drive you will install to. Make sure you have selected the correct drive!. Again, a quick {{ic|lsblk}} will work here.<br />
<br />
# $DRIVE=/dev/DRIVEID<br />
<br />
(replace /dev/DRIVEID with the correct value, for example /dev/sda, /dev/nvme0n1, etc.)<br />
<br />
If you didn't securely wipe the drive already, it's worth "zapping" it using [[Fdisk#Using_sgdisk|sgdisk]] to remove any lingering legacy partition information. If you already wiped the drive you can skip this command (though it won't hurt to run it again).<br />
<br />
{{Warning|'''This command will also effectively erase the selected drive!'''}}<br />
<br />
# sgdisk --zap-all $DRIVE<br />
<br />
The following command will then create all three partitions in one go. '''It will also effectively erase the selected drive!'''<br />
<br />
# sgdisk --clear \<br />
--new=1:0:+550MiB --typecode=1:ef00 --change-name=1:EFI \<br />
--new=2:0:+8GiB --typecode=2:8200 --change-name=2:cryptswap \<br />
--new=3:0:0 --typecode=2:8200 --change-name=3:cryptsystem \<br />
$DRIVE<br />
<br />
It is worth noting that the "--change-name" values are, in this case, creating GPT "partition labels". You can subsequently see these by using the {{ic|lsblk -o +PARTLABEL}} command. It is good to use "EFI" for the efi partition. I am not aware of UEFI implementations that actively use the label for identification of the EFI partition, but it is possible that some do (UEFI bios implementations are not always consistent or to spec). The other two names are entirely "arbitrary". There is nothing special about calling them cryptswap and cryptsystem; they are simply good, clear names that remind us of the purpose of this partition and what it contains (for example, "cryptswap" suggests "this partition is for swap, and is encrypted").<br />
<br />
One final note about partition labels: we want them to be unique on your system. If for some reason there is already a GPT partition with the name EFI on another drive on your system, either change that partition name or use something besides "EFI" to avoid a namespace collision.<br />
<br />
Note also, that the backslashes at the end of each line can be omitted if you are writing the command on one long line instead. Those simply allow the splitting of a single command onto multiple lines.<br />
<br />
=== Format EFI Partition ===<br />
<br />
Next up: format the first (EFI) partition using the (required) FAT32 filesystem.<br />
<br />
# mkfs.fat -F32 -n EFI /dev/disk/by-partlabel/EFI<br />
<br />
Note that we here make use of the partition label we just assigned. I prefer doing this since it simplifies scripts significantly for me and makes them, in my opinion, more readable.<br />
<br />
=== Encrypt System Partition ===<br />
<br />
Encrypt the main partition. Use a good passphrase. Note that the "--align-payload" value has been used as per [http://www.spinics.net/lists/dm-crypt/msg02421.html this suggestion/explanation] on the dm-crypt mailing list.<br />
<br />
Note also that I selected the encryption algorithm and key size using cryptsetup benchmark. See the [[Dm-crypt/Device_encryption]] article for more details.<br />
<br />
# cryptsetup luksFormat --align-payload=8192 -s 256 -c aes-xts-plain64 /dev/disk/by-partlabel/cryptsystem<br />
<br />
After creating the encrypted container, open it. Again, note the use of the partition label to identify the drive. Additionally, note that once we open this device we are giving it a name of "system." Thus "cryptsystem" is the encrypted system partition, while "system" is the name we are using once it has been opened in an unencrypted state. These names are arbitrary (Linux doesn't care what we use) but they help us keep things organized during this process.<br />
<br />
# cryptsetup open /dev/disk/by-partlabel/cryptsystem system<br />
<br />
=== Bring Up Encrypted Swap ===<br />
<br />
Finally we create encrypted swap. In this example we are not enabling hibernation. I will provide information on how to enable hibernation separately. Again, using partition labels to identify the partition and going from "cryptswap" to just "swap".<br />
<br />
We are not using LUKS here (which effectively makes dm-crypt easier to use). We're just using plain dm-crypt to encrypt the swap partition using a random key.<br />
<br />
# cryptsetup open --type plain --key-file /dev/urandom /dev/disk/by-partlabel/cryptswap swap<br />
# mkswap -L swap /dev/mapper/swap<br />
# swapon -L swap<br />
<br />
=== Create BTRFS Subvolumes ===<br />
<br />
Now on to the main attraction: creating our BTRFS subvolume structure. While BTRFS can be set up like any other filesystem (single command, just use the created file system directly), we're going to use the power of BTRFS to enable snapshotting our system state efficiently and rollbacks as necessary.<br />
<br />
First we create a top-level BTRFS subvolume. Note that the top-level entity in BTRFS nomenclature is still referred to as a '''sub'''volume, despite being at the top-level.<br />
<br />
We will create and mount this subvolume, create some new subvolumes inside it, and then switch to those subvolumes as our proper, mounted filesystems. Doing this will enable us to treat our root filesystem as a snapshotable object.<br />
<br />
Top-level subvolume creation.<br />
<br />
# mkfs.btrfs --force --label system /dev/mapper/system<br />
<br />
Temporarily mount our top-level volume for further subvolume creation. Note that the variable 'o' in this case is our default set of options for any given filesystem mount, while "o_btrfs" are those plus some options specific to btrfs. The default option "x-mount.mkdir" is a neat trick that allows us to skip the creation of directories for mountpoints (they will be created automatically). We assume /mnt as the standard mount point, as in a normal Arch Linux installation.<br />
<br />
# o=defaults,x-mount.mkdir<br />
# o_btrfs=$o,compress=lzo,ssd,noatime<br />
<br />
Note the use of our filesystem label to mount our subvolume. This is distinct from the partition labels used earlier. See the Arch wiki article on [[Persistent_block_device_naming]] for more information.<br />
<br />
# mount -t btrfs LABEL=system /mnt<br />
<br />
Now we create the subvolumes which will actually be mounted in our running system:<br />
<br />
# btrfs subvolume create /mnt/root<br />
# btrfs subvolume create /mnt/home<br />
# btrfs subvolume create /mnt/snapshots<br />
<br />
Then we unmount everything...<br />
<br />
# umount -R /mnt<br />
<br />
And remount just the subvolumes under our top-level subvolume (which remains unmounted unless we need to do "surgery" and rollback to a previous system system):<br />
<br />
# mount -t btrfs -o subvol=root,$o_btrfs LABEL=system /mnt<br />
<br />
Before mounting the home and snapshots subvolumes, let's walk through that command so we understand what it's doing:<br />
<br />
The 'mount -t btrfs' just specifies that our filesystem is of type BTRFS. This is often not necessary since mount will attempt to identify the filesystem type, but being explicit is often the best strategy with command line utilities, so we identify the type here.<br />
<br />
We use our previously defined mount options with the $o_btrfs variable and add the additional option "subvol=root" (separating it from our other defaults with a comma, of course). The next part of the command is "LABEL=system". Combined this reads as "mount the filesystem with the 'system' label, and use the 'root' subvolume within that".<br />
<br />
Finally, all this gets mounted at our install root, which in this case is "/mnt".<br />
<br />
Now let's pick back up and mount our home and snapshots subvolumes. Note that while the subvolume name is "snapshots", we will mount it at ".snapshots" (note dot prefix for the mount point). This will keep our root directory listing clean but will still make it available at a reasonable mount location.<br />
<br />
# mount -t btrfs -o subvol=home,$o_btrfs LABEL=system /mnt/home<br />
# mount -t btrfs -o subvol=snapshots,$o_btrfs LABEL=system /mnt/.snapshots<br />
<br />
It it worth noting that in each case we are telling mount to use the same filesystem, namely the one labeled "system". However in each case we are also telling it to look for a different subvolume in that filesystem (via the "subvol=" option).<br />
<br />
With this done, we can move on to installing the actual system.<br />
<br />
== Installation of Base Arch Linux System ==<br />
<br />
We are currently running off the Arch installer root filesystem. We will first use the 'pacstrap' utility to start our installation and then we will boot into our new minimal system using systemd-nspawn.<br />
<br />
=== Install base package group ===<br />
<br />
# pacstrap /mnt base<br />
<br />
=== fstab Generation and Modification ===<br />
<br />
{{Note|In a simpler, non encrypted configuration it is possible to skip making an fstab altogether due to a standard known as the [https://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/ Discoverable Partitions Spec]. However given the complexity of our encrypted, btrfs subvolume configuration, we require an fstab at this time. It is possible that in future we might feasibly do away with the fstab almost entirely in this setup (see the [https://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/#whataboutautomaticmountingofbtrfssubvolumestovarhomeandsoon 'What about automatic mounting of btrfs subvolumes'] section on that page).}}<br />
<br />
Create an [[fstab]] filesystem table file, using labels (-L) to identify the filesystems.<br />
<br />
# genfstab -L -p /mnt >> /mnt/etc/fstab<br />
<br />
I prefer to use labels as this makes the system more portable to a backup drive. You should end up with something that looks pretty close to this:<br />
<br />
{{hc|# cat /mnt/etc/fstab|<nowiki><br />
# /dev/mapper/system UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=system / btrfs rw,noatime,compress=lzo,ssd,space_cache,subvolid=257,subvol=/root,subvol=root 0 0<br />
<br />
# /dev/mapper/system UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=system /home btrfs rw,noatime,compress=lzo,ssd,space_cache,subvolid=258,subvol=/home,subvol=home 0 0<br />
<br />
# /dev/mapper/system UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=system /.snapshots btrfs rw,noatime,compress=lzo,ssd,space_cache,subvolid=259,subvol=/snapshots,subvol=snapshots 0 0<br />
<br />
# /dev/nvme0n1p1 UUID=xxxx-xxxx<br />
LABEL=EFI /boot/EFI vfat rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro 0 2<br />
<br />
# /dev/mapper/swap UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=swap none swap defaults 0 0<br />
</nowiki>}}<br />
<br />
There is one problem, however. Swap will not remount this way (the plain dm-crypt partition with a random key will not have a label when it is recreated on reboot). You will have to change that line from this:<br />
<br />
{{bc|<nowiki>LABEL=swap none swap defaults 0 0</nowiki>}}<br />
<br />
to this:<br />
<br />
{{bc|/dev/mapper/swap none swap defaults 0 0}}<br />
<br />
This will ensure that the mapped device is opened as swap successfully. The other lines may remain unchanged.<br />
<br />
==== Use {{ic|sed}} instead ====<br />
<br />
As a (scriptable) alternative to the manual editing of your {{ic|/etc/fstab}} you could use {{Man|1|sed}} to edit the file in place:<br />
<br />
# sed -i s+LABEL=swap+/dev/mapper/swap+ /mnt/etc/fstab_labels<br />
<br />
=== Boot into new system ===<br />
<br />
{{Warning|While this works, I am fairly certain I'll want to double check some things before declaring this step final. Specifically I want to consider some bind mounts and whether there is anything that should be r/w instead of r/o as is normal in a systemd-nspawn container.}}<br />
<br />
# systemd-nspawn -bD /mnt<br />
<br />
This will boot your new base Arch Linux system. After the standard boot messages scroll by you will be presented with a login (enter {{ic|root}} and hit enter to login).<br />
<br />
=== Generate and set locale ===<br />
<br />
Next, edit and uncomment your desired locale(s) from {{ic|/etc/locale.gen}}. We use {{ic|vi}} in the example below, but you could use a simpler editor such as {{ic|nano}} if you wish.<br />
<br />
{{hc|vi /etc/locale.gen|<nowiki><br />
...<br />
#en_PH.UTF-8 UTF-8<br />
#en_PH ISO-8859-1<br />
#en_SG.UTF-8 UTF-8<br />
#en_SG ISO-8859-1<br />
#en_US.UTF-8 UTF-8<br />
#en_US ISO-8859-1<br />
#en_ZA.UTF-8 UTF-8<br />
#en_ZA ISO-8859-1<br />
#en_ZM UTF-8<br />
...<br />
</nowiki>}}<br />
<br />
Changing it to (for en_US.UTF-8 as a locale in this example):<br />
<br />
{{bc|<nowiki><br />
...<br />
#en_PH.UTF-8 UTF-8<br />
#en_PH ISO-8859-1<br />
#en_SG.UTF-8 UTF-8<br />
#en_SG ISO-8859-1<br />
en_US.UTF-8 UTF-8<br />
#en_US ISO-8859-1<br />
#en_ZA.UTF-8 UTF-8<br />
#en_ZA ISO-8859-1<br />
#en_ZM UTF-8<br />
...<br />
</nowiki>}}<br />
<br />
Alternately one could simply append a known value to the {{ic|/etc/locale.gen}} file:<br />
<br />
# echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen<br />
<br />
After either method, one runs the {{ic|locale-gen}} command to generate the locale files:<br />
<br />
# locale-gen<br />
<br />
Finally we use {{Man|1|systemd-firstboot}} or {{Man|1|localectl}} to set the system locale. Each of these effectively does the same thing which is to simply write to {{ic|/etc/locale.conf}} (which can simply be edited directly as per standard Arch install instructions).<br />
<br />
==== With systemd-firstboot ====<br />
<br />
{{Man|1|systemd-firstboot}} will prompt us for selection from our generated locales. It will only work if there is no assigned system locale. If you wish to make changes afterward you can use {{Man|1|localectl}}<br />
<br />
# systemd-firstboot --prompt-locale<br />
<br />
==== With localectl ====<br />
<br />
This is an alternate to using {{ic|systemd-firstboot --prompt-locale}}. It may also be used subsequent to that command if further changes to the locale are desired.<br />
<br />
If you need a reminder of which locales have been installed (during this install or later during system changes), use {{ic|localectl list-locales}}:<br />
<br />
{{hc|<nowiki># localectl list-locales</nowiki>|en_US.UTF-8}}<br />
<br />
We then use {{ic|localectl set-locale}}:<br />
<br />
# localectl set-locale LANG=en_US.UTF-8<br />
<br />
=== Time and Date ===<br />
<br />
Unless you have a reason not to, we'll turn on NTP synchronization.<br />
<br />
# timedatectl set-ntp 1<br />
<br />
Then list timezones and pick one<br />
<br />
{{hc|<nowiki># timedatectl list-timezones</nowiki>|<nowiki><br />
...<br />
America/Kentucky/Louisville<br />
America/Kentucky/Monticello<br />
America/Kralendijk<br />
America/La_Paz<br />
America/Lima<br />
America/Los_Angeles<br />
America/Lower_Princes<br />
America/Maceio<br />
America/Managua<br />
America/Manaus<br />
America/Marigot<br />
America/Martinique<br />
America/Matamoros<br />
...<br />
</nowiki>}}<br />
# timedatectl set-timezone America/Los_Angeles<br />
<br />
=== Set hostname ===<br />
<br />
# hostnamectl set-hostname myhostname<br />
<br />
See the man page for {{Man|1|hostnamectl}} for other attributes that can be set. You might also add the hostname to {{Man|5|hosts}}:<br />
<br />
{{hc|/etc/hosts|<br />
127.0.0.1 localhost.localdomain localhost<br />
::1 localhost.localdomain localhost<br />
'''127.0.1.1 ''myhostname''.localdomain ''myhostname'''''<br />
}}<br />
<br />
Use {{ic|echo}} for a scriptable solution:<br />
<br />
# echo "127.0.1.1 myhostname.localdomain myhostname" >> /etc/hosts<br />
<br />
=== Network configuration ===<br />
<br />
Configure the network for the newly installed environment: see [[Network configuration]].<br />
<br />
For [[Wireless configuration]], [[Help:Reading#Installation of packages|install]] the {{Pkg|iw}}, {{Pkg|wpa_supplicant}}, and {{Pkg|dialog}} packages, as well as needed [[Wireless#Installing driver/firmware|firmware packages]].<br />
<br />
=== Base Package Installation ===<br />
<br />
We've already included the {{Grp|base}} group which is, strictly speaking, all you need to boot a minimal Arch Linux system. At this stage, however, we can install some useful utilities (and Xorg or Wayland, etc.).<br />
<br />
# pacman -Syu base-devel btrfs-progs iw gptfdisk zsh vim terminus-font<br />
<br />
=== Initramfs ===<br />
<br />
Creating a new ''initramfs'' is usually not required, because [[mkinitcpio]] was run on installation of the {{Pkg|linux}} package with ''pacstrap''. However we'll need to make some changes to the hooks used on our system. Additionally, I switched over to using the systemd hooks in mkinitcpio, so that is largely what you'll see in my example below.<br />
<br />
I recommend making a backup of your {{ic|/etc/mkinitcpio.conf}} file first:<br />
<br />
# mv /etc/mkinitcpio.conf /etc/mkinitcpio.conf.orig<br />
<br />
and then editing a new file to match the following contents:<br />
<br />
{{bc|<nowiki><br />
MODULES=""<br />
BINARIES=""<br />
FILES=""<br />
HOOKS="base systemd sd-vconsole modconf keyboard block filesystems btrfs sd-encrypt fsck"<br />
</nowiki>}}<br />
<br />
Finally, recreate the initramfs image:<br />
<br />
# mkinitcpio -p linux<br />
<br />
=== Bootloader ===<br />
<br />
{{Warning|THIS SECTION IN PROGRESS}}<br />
<br />
=== Root password ===<br />
<br />
Set the root [[password]]:<br />
<br />
# passwd<br />
<br />
=== Leave the systemd-nspawn environment ===<br />
<br />
Issue a poweroff to exit the nspawned environment:<br />
<br />
# poweroff<br />
<br />
This will return you the Arch installer environment where you can wrap up.<br />
<br />
=== Legacy boot loader ===<br />
<br />
If your system is not UEFI and you need to use a legacy installer like grub, it will need to be installed from within an arch-chroot generated chroot, not the systemd-nspawn running container. An example of this would be (assuming that the drive of the new system is at /dev/sdb):<br />
<br />
# arch-chroot /mnt<br />
# grub-install $DRIVE<br />
# grub-mkconfig -o /boot/grub/grub.cfg<br />
# exit<br />
<br />
== Command Summary ==<br />
<br />
The following are all critical commands (exluded: the initial drive wipe which is optional). It assumes you have successfully brought up networking prior to starting this sequence.<br />
<br />
{{bc|<nowiki><br />
<br />
$DRIVE=/dev/DRIVEID<br />
<br />
sgdisk --zap-all $DRIVE<br />
<br />
sgdisk --clear \<br />
--new=1:0:+550MiB --typecode=1:ef00 --change-name=1:EFI \<br />
--new=2:0:+8GiB --typecode=2:8200 --change-name=2:cryptswap \<br />
--new=3:0:0 --typecode=2:8200 --change-name=3:cryptsystem \<br />
$DRIVE<br />
<br />
mkfs.fat -F32 -n EFI /dev/disk/by-partlabel/EFI<br />
<br />
cryptsetup luksFormat --align-payload=8192 -s 256 -c aes-xts-plain64 /dev/disk/by-partlabel/cryptsystem<br />
<br />
cryptsetup open /dev/disk/by-partlabel/cryptsystem system<br />
<br />
cryptsetup open --type plain --key-file /dev/urandom /dev/disk/by-partlabel/cryptswap swap<br />
<br />
mkswap -L swap /dev/mapper/swap<br />
<br />
swapon -L swap<br />
<br />
mkfs.btrfs --force --label system /dev/mapper/system<br />
<br />
o=defaults,x-mount.mkdir<br />
<br />
o_btrfs=$o,compress=lzo,ssd,noatime<br />
<br />
mount -t btrfs LABEL=system /mnt<br />
<br />
btrfs subvolume create /mnt/root<br />
<br />
btrfs subvolume create /mnt/home<br />
<br />
btrfs subvolume create /mnt/snapshots<br />
<br />
umount -R /mnt<br />
<br />
mount -t btrfs -o subvol=root,$o_btrfs LABEL=system /mnt<br />
<br />
mount -t btrfs -o subvol=home,$o_btrfs LABEL=system /mnt/home<br />
<br />
mount -t btrfs -o subvol=snapshots,$o_btrfs LABEL=system /mnt/.snapshots<br />
<br />
pacstrap /mnt base<br />
<br />
genfstab -L -p /mnt >> /mnt/etc/fstab<br />
<br />
sed -i "s+LABEL=swap+/dev/mapper/swap" /etc/fstab_labels<br />
<br />
systemd-nspawn -bD /mnt<br />
<br />
echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen<br />
<br />
locale-gen<br />
<br />
localectl set-locale LANG=en_US.UTF-8<br />
<br />
timedatectl set-ntp 1<br />
<br />
timedatectl set-timezone America/Los_Angeles<br />
<br />
hostnamectl set-hostname myhostname<br />
<br />
echo "127.0.1.1 myhostname.localdomain myhostname" >> /etc/hosts<br />
<br />
pacman -Syu base-devel btrfs-progs iw gptfdisk zsh vim terminus-font<br />
</nowiki>}}<br />
<br />
== Quick and Dirty ==<br />
<br />
{{Note|an extra example and may be moved to its own wiki page later}}<br />
<br />
This is the approximate process I follow if I want to bring up Arch on, say, an old laptop for a quick purpose built test machine, etc. It's not an install that I consider long term maintainable since rollbacks aren't implemented, nor is there any encryption, but it's a good example of how simple installation can be.<br />
<br />
{{bc|<nowiki><br />
$DRIVE=/dev/DRIVEID<br />
sgdisk --zap-all $DRIVE<br />
mkfs.btrfs -f $DRIVE<br />
mount -t btrfs $DRIVE /mnt<br />
pacstrap /mnt base<br />
systemd-nspawn -bD /mnt<br />
echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen<br />
locale-gen<br />
localectl set-locale LANG=en_US.UTF-8<br />
timedatectl set-ntp 1<br />
timedatectl set-timezone America/Los_Angeles<br />
hostnamectl set-hostname myhostname<br />
poweroff<br />
arch-chroot /mnt<br />
grub-install --root-directory=/mnt $DRIVE<br />
grub-mkconfig -o /mnt/boot/grub/grub.cfg<br />
exit<br />
reboot<br />
</nowiki>}}</div>Altercationhttps://wiki.archlinux.org/index.php?title=User:Altercation/Bullet_Proof_Arch_Install&diff=458643User:Altercation/Bullet Proof Arch Install2016-12-06T17:39:54Z<p>Altercation: /* Format EFI Partition */</p>
<hr />
<div>This page is a summary of the current process I follow when installing Arch on a new laptop or desktop. My process varies over time, but this serves as my "state of the art" best practice recommendations. I'm open to feedback and suggestions for improvements.<br />
<br />
{{Note|This is entirely based on my own opinions and research. It is opinionated about the best way to do things given the current state of the kernel, hardware availability, and utilities, filesystems, etc. I will explain my rationale for specific choices and provide links to other sources of information (on the Arch wiki or external) where useful.}}<br />
<br />
== Objectives ==<br />
<br />
The goals of my standard "bullet proof" Arch Linux installation are:<br />
<br />
* Benefit from Arch's rolling release model while mitigating any risk of system corruption or data loss due to failed upgrades<br />
* Minimize risk due to hardware failure or total system loss (e.g. theft or physical destruction)<br />
* Make system rollbacks easy and procedural, using a standard setup and methodology for recovery of previous system (and user data) states<br />
<br />
=== Why not the Arch Install instructions? ===<br />
<br />
The [[Installation guide|Arch Linux installation instructions]] are an excellent, general starting point and you should read and understand them. That being said, they are designed to map to a very, very broad set of installation scenarios. I am interested in a very specific type of installation (daily use desktops and laptops in this article) and I have a strong set of opinions about the "right" or "best practice" way to set up my own working systems.<br />
<br />
These instructions, then, are much more prescriptive and have strong suggestions or directions about how (and why) one should use a particular method during Arch Linux installation.<br />
<br />
=== Key differences from the stock Arch install instructions ===<br />
<br />
How these instructions differ from the standard Arch guidance:<br />
<br />
* We are encrypting the entire system but not using LVM as is often recommended (see the encryption section below for details about why we are not using it).<br />
* I use labels and avoid UUIDs where possible to make switching to an alternate recovery drive easier.<br />
* I skip arch-chroot and simply boot the new system ('''not''' reboot, just boot) from within the install environment using {{Man|1|systemd-nspawn}} which enables the *ctl commands to work (and systemd services to be enabled properly without need for a system reboot)<br />
* I use the various systemd *ctl commands (hostnamectl, timedatectl, localectl, etc.) to configure the system<br />
* I use the systemd mkinitcpio hooks in lieu of the legacy hooks.<br />
* I use BTRFS exclusively for root and home partitions for its backup capabilities.<br />
* I recommend and use secure boot (but not with the Microsoft keys) to minimize risk due to the unavoidably unencrypted EFI partition.<br />
<br />
== Assumptions ==<br />
<br />
These instructions presuppose the following:<br />
<br />
* fairly new hardware (these instructions may work on older hardware, but there may be unusual issues that crop up... if you aren't comfortable handling those situations you should consider a more "traditional" Arch Linux install (e.g. using grub, LVM, ext4, etc.)<br />
* [[Unified Extensible Firmware Interface|UEFI support]] (BIOS system install is also possible with some modification of these instructions, but this has not yet been detailed here)<br />
* probably an [[Solid State Drives|SSD]].<br />
* some familiarity with Arch, or at least some experience with Linux, will help<br />
<br />
{{Warning|I am assuming you are going to single boot (not dual boot) and that you are '''willing to wipe all data from the install drive.''' If that is not the case, do not proceed with these instructions as following them '''will effectively destroy any data (and other operating systems) on the installation target drive.'''}}<br />
<br />
== Prerequisites ==<br />
<br />
You must have a recent copy of the Arch install USB. See [[:Category:Getting and installing Arch]] for general information and [[USB flash installation media]] for specific details on creating a USB Arch installation drive.<br />
<br />
You should also have a reasonable amount of time in which to complete the installation. Novice users will want to budget a couple hours. Experienced users will ''know'' to budget a couple hours.<br />
<br />
== Preparation ==<br />
<br />
=== Boot from USB Drive ===<br />
<br />
Boot your system from your prepared [[USB flash installation media|Arch Linux USB drive]]. It is important that you boot in EFI mode, not legacy BIOS compatibility mode. See the [[Unified Extensible Firmware Interface|UEFI]] article for more information about checking boot mode and ensuring you are booting using EFI.<br />
<br />
=== Bring up the network ===<br />
<br />
If you booted into a system with an ethernet cable plugged in, chances are you're up and running. If you need to use wireless instead, {{ic|wifi-menu}} will more often than not work without trouble. If those don't work, see [[Installation guide#Connect to the Internet|the Arch installation guide section on connecting to the internet]].<br />
<br />
=== Select Drive ===<br />
<br />
I like to use the [[Core utilities#lsblk|{{ic|1=lsblk}}]] command to bring up a quick list of the block devices on the system and identify existing partition structures and sizes, as well as mount points. If you don't already use it, I recommend [[Core utilities#lsblk|{{ic|1=lsblk}}]] when you need information on any given drive or partition. It's useful for polling UUIDs as well. For example, the following command gives you a clearly formatted summary of all block devices, their partition labels, filesystem lables, UUIDs and partition UUIDS: {{ic|lsblk -o +LABEL,PARTLABEL,UUID,PARTUUID}}<br />
<br />
In any case, the plain command without options should be enough to identify the drive you will install to (for example {{ic|1=/dev/sda}} or {{ic|1=/dev/nvme0n1}}:<br />
<br />
# lsblk<br />
<br />
=== Wipe Drive Securely (optional) ===<br />
<br />
While it is not necessary, given that this process will go through the trouble of encrypting the main system partition, it makes sense to do a secure wipe of the drive. This is more or less directly from [[Dm-crypt/Drive preparation#dm-crypt wipe on an empty disk or partition]].<br />
<br />
{{Warning|Be certain of your target device selection as we will be '''wiping this drive''' (either securely or, at minimum, destroying all existing partition data).}}<br />
<br />
First, create a temporary encrypted container the full disk ({{ic|sdX}}) to be encrypted, e.g. using default encryption parameters and a random key via the {{ic|--key-file /dev/{u}random}} option (see also [[Random number generation]]):<br />
<br />
# cryptsetup open --type plain /dev/sdXY container --key-file /dev/urandom<br />
<br />
{{Note|An interesting page addressing myths about /dev/urandom can be [http://www.2uo.de/myths-about-urandom/ found here]}}<br />
<br />
Second, check the container exists:<br />
<br />
{{hc|# fdisk -l|Disk /dev/mapper/container: XXXX MB, XXXXXXXXXX bytes<br />
...<br />
Disk /dev/mapper/container does not contain a valid partition table}}<br />
Wipe the container with zeros. A use of {{ic|1=if=/dev/urandom}} is '''not''' required as the encryption cipher itself generates randomness.<br />
{{hc|# dd <nowiki>if=/dev/zero of=/dev/mapper/container status=progress bs=1M</nowiki>|<br />
dd: writing to ‘/dev/mapper/container’: No space left on device}}<br />
<br />
{{Tip|<br />
* Using ''dd'' with the {{ic|1=bs=}} option, e.g. {{ic|1=bs=1M}} as above, is frequently used to increase disk throughput of the operation.<br />
* To perform a check of the operation, zero the partition before creating the wipe container. After the wipe command {{ic|blockdev --getsize64 ''/dev/mapper/container''}} can be used to get the exact container size as root. Now ''od'' can be used to spotcheck whether the wipe overwrote the zeroed sectors, e.g. {{ic|od -j ''containersize - blocksize''}} to view the wipe completed to the end.}}<br />
<br />
Finally, close the temporary container:<br />
<br />
# cryptsetup close container<br />
<br />
== Partition & Format Drive ==<br />
<br />
=== Understanding some basics about disks, partitions, and filesystems ===<br />
<br />
Think of your drive like a big empty building, no rooms. This is your plain physical drive (either a spinning platter drive or an SSD). Next imagine that to make it useful, we divide the building into apartments. In our analogy the apartments are '''partitions''' of the drive.<br />
<br />
Imagine also that there are a couple different standard methods of creating layout maps to the apartments. These plans are standardized so that the public services that have to access the building regularly (like the fire and police, for example) understand how to find the apartment entrances. In the world of partitioning, the equivalent is the "partition table scheme". The two common schemes are called "MBR" (Master Boot Record, older) and "GPT" (GUID Partition Table, newer). We will be using the new GPT scheme.<br />
<br />
Finally, imagine that the apartments are just empty shells. The act of building walls and laying out the functional structure of the apartments is equivalent to formatting our disk partitions with a filesystem. And just as different layouts may be more or less efficient, or have other different functional characteristics, so to filesystems have different attributes that make them useful in different ways.<br />
<br />
=== Our partition plans ===<br />
<br />
We will take our physical drive and divide it into three partitions. These partitions each serve a distinct purpose. All but the first and smallest, the EFI partition, will be encrypted. For security, if your system supports Secure Boot, you may choose to cryptographically sign the data stored on the EFI partition so that any tampering will be evident, despite the lack of encryption on that partition.<br />
<br />
{{Note|Again, we're assuming an UEFI installation (not legacy BIOS) and a GPT (not MBR) partition structure. If none of that made sense, best to start with the [[Partitioning]] article or do some test installs of Arch first. '''Partitioning is, in my opinion, one of the areas that is most confusing for the new Arch user.''' Additionally, there is a lot "received wisdom" and cargo-cult assumption making about how best to partition. Working through some of the "this is how it's always been done" tutorials isn't necessarily a bad thing... In many cases the way it has always been done has some sound reasoning behind it, despite being cargo-culted half the time. That being said, the method presented here is different from that in most of the Arch wiki partitioning methodologies.}}<br />
<br />
We will not be using LVM. You read a lot about LUKS and LVM and it all gets a bit complicated (LVM on LUKS, LUKS on LVM, etc.). LVM is a "logical volume manager" and abstracts physical devices (drives) into virtual devices, for easier management. It's a good idea but we will be using btrfs to effectively achieve the same results and really don't need the overhead of LVM.<br />
<br />
=== Partition Summary ===<br />
<br />
* 1: EFI - The UEFI 'bios" will look for this FAT32 formatted partition and either locate a default bootloader or will locate a specific EFI boot entry on it. This partition is by necessity not encrypted (unless the drive it is on has been encrypted as a "self encrypting drive")<br />
* 2: Swap - Used by Linux to swap out pages of memory from RAM to disk. Despite debate in this area, it is advisable to have at least some swap space, even it you are not planning on using hibernation on your machine. The Arch wiki is unfortunately rather too brief in its own [[Swap|swap article]] so I recommend the [https://docs.fedoraproject.org/en-US/Fedora/14/html/Storage_Administration_Guide/ch-swapspace.html Fedora documentation on swap] for a good overview on determining the right swap partition size.<br />
* 3: System - This will hold our root and home data. It will be formatted as BTRFS and will use subvolumes to manage snapshots of the current root and home contents.<br />
<br />
=== Visual overview of our partitions, filesystems, and contents ===<br />
<br />
This is a visual summary of our partions (inc. size information), encryption, filesystems, and a summary of the contents of each container.<br />
<br />
{| class="wikitable"<br />
| style="vertical-align: top; padding:1em" | '''Partition 1 (EFI)'''<br />
550MiB+<br />
{| style="border: 1px solid black; background: #DACEF2; margin: 1em;"<br />
! FAT32<br />
|-<br />
|kernel & initramfs<br />
(signed if using secure boot)<br />
|}<br />
| style="vertical-align: top; padding:1em" | '''Partition 2 (Swap)'''<br />
w/ Hibernate: Equal RAM,<br />
w/o Hibernate: min 8GB<br />
{| style="border: 1px solid black; background: #F2ECCE; margin: 1em;"<br />
|-<br />
! dm-crypt<br />
{| style="border: 1px solid black; background: #DACEF2; margin: 1em;"<br />
| SWAP<br />
|}<br />
|}<br />
| style="vertical-align: top; padding:1em" | '''Partition 3 (System)'''<br />
Remaining Space<br />
{| style="border: 1px solid black; background: #F2ECCE; margin: 1em;"<br />
|-<br />
! LUKS dm-crypt<br />
<br />
{| style="border: 1px solid black; background: #DACEF2; margin: 1em;"<br />
| BTRFS Top Level Subvolume<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Root Subvolume<br />
|}<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Home Subvolume<br />
|}<br />
<br />
{| style="border: 1px solid black; background: #E0CEF2; margin: 1em;"<br />
| BTRFS Snapshots Subvolume<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Root Snapshot Subvolume(s)<br />
|}<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Home Snapshot Subvolume(s)<br />
|}<br />
<br />
|}<br />
<br />
|}<br />
<br />
|}<br />
<br />
|}<br />
<br />
=== Partition Drive ===<br />
<br />
There are many utilities available for [[Partitioning]]. Because we are using Arch Linux and the command line doesn't hurt us (it makes us stronger) we will be using pure, non-interactive command line tools for this. Specifically, we will be using the utility [[Fdisk#Using_sgdisk|sgdisk]] from the {{Pkg|gptfdisk}} package. The [[Fdisk|fdisk]] utility now also supports GPT partitioned drives, so it would be an alternative. [[Fdisk#Using_sgdisk|sgdisk]] is available by default on the standard Arch install iso that you use to make your bootable USB drive.<br />
<br />
First, select the drive you will install to. Make sure you have selected the correct drive!. Again, a quick {{ic|lsblk}} will work here.<br />
<br />
# $DRIVE=/dev/DRIVEID<br />
<br />
(replace /dev/DRIVEID with the correct value, for example /dev/sda, /dev/nvme0n1, etc.)<br />
<br />
If you didn't securely wipe the drive already, it's worth "zapping" it using [[Fdisk#Using_sgdisk|sgdisk]] to remove any lingering legacy partition information. If you already wiped the drive you can skip this command (though it won't hurt to run it again).<br />
<br />
{{Warning|'''This command will also effectively erase the selected drive!'''}}<br />
<br />
# sgdisk --zap-all $DRIVE<br />
<br />
The following command will then create all three partitions in one go. '''It will also effectively erase the selected drive!'''<br />
<br />
# sgdisk --clear \<br />
--new=1:0:+550MiB --typecode=1:ef00 --change-name=1:EFI \<br />
--new=2:0:+8GiB --typecode=2:8200 --change-name=2:cryptswap \<br />
--new=3:0:0 --typecode=2:8200 --change-name=3:cryptsystem \<br />
$DRIVE<br />
<br />
It is worth noting that the "--change-name" values are, in this case, creating GPT "partition labels". You can subsequently see these by using the {{ic|lsblk -o +PARTLABEL}} command. It is good to use "EFI" for the efi partition. I am not aware of UEFI implementations that actively use the label for identification of the EFI partition, but it is possible that some do (UEFI bios implementations are not always consistent or to spec). The other two names are entirely "arbitrary". There is nothing special about calling them cryptswap and cryptsystem; they are simply good, clear names that remind us of the purpose of this partition and what it contains (for example, "cryptswap" suggests "this partition is for swap, and is encrypted").<br />
<br />
One final note about partition labels: we want them to be unique on your system. If for some reason there is already a GPT partition with the name EFI on another drive on your system, either change that partition name or use something besides "EFI" to avoid a namespace collision.<br />
<br />
Note also, that the backslashes at the end of each line can be omitted if you are writing the command on one long line instead. Those simply allow the splitting of a single command onto multiple lines.<br />
<br />
=== Format EFI Partition ===<br />
<br />
Next up: format the first (EFI) partition using the (required) FAT32 filesystem.<br />
<br />
# mkfs.fat -F32 -n EFI /dev/disk/by-partlabel/EFI<br />
<br />
Note that we here make use of the partition label we just assigned. I prefer doing this since it simplifies scripts significantly for me and makes them, in my opinion, more readable.<br />
<br />
=== Encrypt System Partition ===<br />
<br />
Encrypt the main partition. Use a good passphrase. Note that the "--align-payload" value has been used as per [http://www.spinics.net/lists/dm-crypt/msg02421.html this suggestion/explanation] on the dm-crypt mailing list.<br />
<br />
Note also that I selected the encryption algorithm and key size using cryptsetup benchmark. See the [[Dm-crypt/Device_encryption]] article for more details.<br />
<br />
# cryptsetup luksFormat --align-payload=8192 -s 256 -c aes-xts-plain64 /dev/disk/by-partlabel/cryptsystem<br />
<br />
After creating the encrypted container, open it. Again, note the use of the partition label to identify the drive. Additionally, note that once we open this device we are giving it a name of "system." Thus "cryptsystem" is the encrypted system partition, while "system" is the name we are using once it has been opened in an unencrypted state. These names are arbitrary (Linux doesn't care what we use) but they help us keep things organized during this process.<br />
<br />
# cryptsetup open /dev/disk/by-partlabel/cryptsystem system<br />
<br />
=== Bring Up Encrypted Swap ===<br />
<br />
Finally we create encrypted swap. In this example we are not enabling hibernation. I will provide information on how to enable hibernation separately. Again, using partition labels to identify the partition and going from "cryptswap" to just "swap".<br />
<br />
We are not using LUKS here (which effectively makes dm-crypt easier to use). We're just using plain dm-crypt to encrypt the swap partition using a random key.<br />
<br />
# cryptsetup open --type plain --key-file /dev/urandom /dev/disk/by-partlabel/cryptswap swap<br />
# mkswap -L swap /dev/mapper/swap<br />
# swapon -L swap<br />
<br />
=== Create BTRFS Subvolumes ===<br />
<br />
Now on to the main attraction: creating our BTRFS subvolume structure. While BTRFS can be set up like any other filesystem (single command, just use the created file system directly), we're going to use the power of BTRFS to enable snapshotting our system state efficiently and rollbacks as necessary.<br />
<br />
First we create a top-level BTRFS subvolume. Note that the top-level entity in BTRFS nomenclature is still referred to as a '''sub'''volume, despite being at the top-level.<br />
<br />
We will create and mount this subvolume, create some new subvolumes inside it, and then switch to those subvolumes as our proper, mounted filesystems. Doing this will enable us to treat our root filesystem as a snapshotable object.<br />
<br />
Top-level subvolume creation.<br />
<br />
# mkfs.btrfs --force --label system /dev/mapper/system<br />
<br />
Temporarily mount our top-level volume for further subvolume creation. Note that the variable 'o' in this case is our default set of options for any given filesystem mount, while "o_btrfs" are those plus some options specific to btrfs. The default option "x-mount.mkdir" is a neat trick that allows us to skip the creation of directories for mountpoints (they will be created automatically). We assume /mnt as the standard mount point, as in a normal Arch Linux installation.<br />
<br />
# o=defaults,x-mount.mkdir<br />
# o_btrfs=$o,compress=lzo,ssd,noatime<br />
<br />
Note the use of our filesystem label to mount our subvolume. This is distinct from the partition labels used earlier. See the Arch wiki article on [[Persistent_block_device_naming]] for more information.<br />
<br />
# mount -t btrfs LABEL=system /mnt<br />
<br />
Now we create the subvolumes which will actually be mounted in our running system:<br />
<br />
# btrfs subvolume create /mnt/root<br />
# btrfs subvolume create /mnt/home<br />
# btrfs subvolume create /mnt/snapshots<br />
<br />
Then we unmount everything...<br />
<br />
# umount -R /mnt<br />
<br />
And remount just the subvolumes under our top-level subvolume (which remains unmounted unless we need to do "surgery" and rollback to a previous system system):<br />
<br />
# mount -t btrfs -o subvol=root,$o_btrfs LABEL=system /mnt<br />
<br />
Before mounting the home and snapshots subvolumes, let's walk through that command so we understand what it's doing:<br />
<br />
The 'mount -t btrfs' just specifies that our filesystem is of type BTRFS. This is often not necessary since mount will attempt to identify the filesystem type, but being explicit is often the best strategy with command line utilities, so we identify the type here.<br />
<br />
We use our previously defined mount options with the $o_btrfs variable and add the additional option "subvol=root" (separating it from our other defaults with a comma, of course). The next part of the command is "LABEL=system". Combined this reads as "mount the filesystem with the 'system' label, and use the 'root' subvolume within that".<br />
<br />
Finally, all this gets mounted at our install root, which in this case is "/mnt".<br />
<br />
Now let's pick back up and mount our home and snapshots subvolumes. Note that while the subvolume name is "snapshots", we will mount it at ".snapshots" (note dot prefix for the mount point). This will keep our root directory listing clean but will still make it available at a reasonable mount location.<br />
<br />
# mount -t btrfs -o subvol=home,$o_btrfs LABEL=system /mnt/home<br />
# mount -t btrfs -o subvol=snapshots,$o_btrfs LABEL=system /mnt/.snapshots<br />
<br />
It it worth noting that in each case we are telling mount to use the same filesystem, namely the one labeled "system". However in each case we are also telling it to look for a different subvolume in that filesystem (via the "subvol=" option).<br />
<br />
With this done, we can move on to installing the actual system.<br />
<br />
== Installation of Base Arch Linux System ==<br />
<br />
We are currently running off the Arch installer root filesystem. We will first use the 'pacstrap' utility to start our installation and then we will boot into our new minimal system using systemd-nspawn.<br />
<br />
=== Install base package group ===<br />
<br />
# pacstrap /mnt base<br />
<br />
=== fstab Generation and Modification ===<br />
<br />
{{Note|In a simpler, non encrypted configuration it is possible to skip making an fstab altogether due to a standard known as the [https://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/ Discoverable Partitions Spec]. However given the complexity of our encrypted, btrfs subvolume configuration, we require an fstab at this time. It is possible that in future we might feasibly do away with the fstab almost entirely in this setup (see the [https://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/#whataboutautomaticmountingofbtrfssubvolumestovarhomeandsoon 'What about automatic mounting of btrfs subvolumes'] section on that page).}}<br />
<br />
Create an [[fstab]] filesystem table file, using labels (-L) to identify the filesystems.<br />
<br />
# genfstab -L -p /mnt >> /mnt/etc/fstab<br />
<br />
I prefer to use labels as this makes the system more portable to a backup drive. You should end up with something that looks pretty close to this:<br />
<br />
{{hc|# cat /mnt/etc/fstab|<nowiki><br />
# /dev/mapper/system UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=system / btrfs rw,noatime,compress=lzo,ssd,space_cache,subvolid=257,subvol=/root,subvol=root 0 0<br />
<br />
# /dev/mapper/system UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=system /home btrfs rw,noatime,compress=lzo,ssd,space_cache,subvolid=258,subvol=/home,subvol=home 0 0<br />
<br />
# /dev/mapper/system UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=system /.snapshots btrfs rw,noatime,compress=lzo,ssd,space_cache,subvolid=259,subvol=/snapshots,subvol=snapshots 0 0<br />
<br />
# /dev/nvme0n1p1 UUID=xxxx-xxxx<br />
LABEL=EFI /boot/EFI vfat rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro 0 2<br />
<br />
# /dev/mapper/swap UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=swap none swap defaults 0 0<br />
</nowiki>}}<br />
<br />
There is one problem, however. Swap will not remount this way (the plain dm-crypt partition with a random key will not have a label when it is recreated on reboot). You will have to change that line from this:<br />
<br />
{{bc|<nowiki>LABEL=swap none swap defaults 0 0</nowiki>}}<br />
<br />
to this:<br />
<br />
{{bc|/dev/mapper/swap none swap defaults 0 0}}<br />
<br />
This will ensure that the mapped device is opened as swap successfully. The other lines may remain unchanged.<br />
<br />
==== Use {{ic|sed}} instead ====<br />
<br />
As a (scriptable) alternative to the manual editing of your {{ic|/etc/fstab}} you could use {{Man|1|sed}} to edit the file in place:<br />
<br />
# sed -i "s+LABEL=swap+/dev/mapper/swap" /etc/fstab_labels<br />
<br />
=== Boot into new system ===<br />
<br />
{{Warning|While this works, I am fairly certain I'll want to double check some things before declaring this step final. Specifically I want to consider some bind mounts and whether there is anything that should be r/w instead of r/o as is normal in a systemd-nspawn container.}}<br />
<br />
# systemd-nspawn -bD /mnt<br />
<br />
This will boot your new base Arch Linux system. After the standard boot messages scroll by you will be presented with a login (enter {{ic|root}} and hit enter to login).<br />
<br />
=== Generate and set locale ===<br />
<br />
Next, edit and uncomment your desired locale(s) from {{ic|/etc/locale.gen}}. We use {{ic|vi}} in the example below, but you could use a simpler editor such as {{ic|nano}} if you wish.<br />
<br />
{{hc|vi /etc/locale.gen|<nowiki><br />
...<br />
#en_PH.UTF-8 UTF-8<br />
#en_PH ISO-8859-1<br />
#en_SG.UTF-8 UTF-8<br />
#en_SG ISO-8859-1<br />
#en_US.UTF-8 UTF-8<br />
#en_US ISO-8859-1<br />
#en_ZA.UTF-8 UTF-8<br />
#en_ZA ISO-8859-1<br />
#en_ZM UTF-8<br />
...<br />
</nowiki>}}<br />
<br />
Changing it to (for en_US.UTF-8 as a locale in this example):<br />
<br />
{{bc|<nowiki><br />
...<br />
#en_PH.UTF-8 UTF-8<br />
#en_PH ISO-8859-1<br />
#en_SG.UTF-8 UTF-8<br />
#en_SG ISO-8859-1<br />
en_US.UTF-8 UTF-8<br />
#en_US ISO-8859-1<br />
#en_ZA.UTF-8 UTF-8<br />
#en_ZA ISO-8859-1<br />
#en_ZM UTF-8<br />
...<br />
</nowiki>}}<br />
<br />
Alternately one could simply append a known value to the {{ic|/etc/locale.gen}} file:<br />
<br />
# echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen<br />
<br />
After either method, one runs the {{ic|locale-gen}} command to generate the locale files:<br />
<br />
# locale-gen<br />
<br />
Finally we use {{Man|1|systemd-firstboot}} or {{Man|1|localectl}} to set the system locale. Each of these effectively does the same thing which is to simply write to {{ic|/etc/locale.conf}} (which can simply be edited directly as per standard Arch install instructions).<br />
<br />
==== With systemd-firstboot ====<br />
<br />
{{Man|1|systemd-firstboot}} will prompt us for selection from our generated locales. It will only work if there is no assigned system locale. If you wish to make changes afterward you can use {{Man|1|localectl}}<br />
<br />
# systemd-firstboot --prompt-locale<br />
<br />
==== With localectl ====<br />
<br />
This is an alternate to using {{ic|systemd-firstboot --prompt-locale}}. It may also be used subsequent to that command if further changes to the locale are desired.<br />
<br />
If you need a reminder of which locales have been installed (during this install or later during system changes), use {{ic|localectl list-locales}}:<br />
<br />
{{hc|<nowiki># localectl list-locales</nowiki>|en_US.UTF-8}}<br />
<br />
We then use {{ic|localectl set-locale}}:<br />
<br />
# localectl set-locale LANG=en_US.UTF-8<br />
<br />
=== Time and Date ===<br />
<br />
Unless you have a reason not to, we'll turn on NTP synchronization.<br />
<br />
# timedatectl set-ntp 1<br />
<br />
Then list timezones and pick one<br />
<br />
{{hc|<nowiki># timedatectl list-timezones</nowiki>|<nowiki><br />
...<br />
America/Kentucky/Louisville<br />
America/Kentucky/Monticello<br />
America/Kralendijk<br />
America/La_Paz<br />
America/Lima<br />
America/Los_Angeles<br />
America/Lower_Princes<br />
America/Maceio<br />
America/Managua<br />
America/Manaus<br />
America/Marigot<br />
America/Martinique<br />
America/Matamoros<br />
...<br />
</nowiki>}}<br />
# timedatectl set-timezone America/Los_Angeles<br />
<br />
=== Set hostname ===<br />
<br />
# hostnamectl set-hostname myhostname<br />
<br />
See the man page for {{Man|1|hostnamectl}} for other attributes that can be set. You might also add the hostname to {{Man|5|hosts}}:<br />
<br />
{{hc|/etc/hosts|<br />
127.0.0.1 localhost.localdomain localhost<br />
::1 localhost.localdomain localhost<br />
'''127.0.1.1 ''myhostname''.localdomain ''myhostname'''''<br />
}}<br />
<br />
Use {{ic|echo}} for a scriptable solution:<br />
<br />
# echo "127.0.1.1 myhostname.localdomain myhostname" >> /etc/hosts<br />
<br />
=== Network configuration ===<br />
<br />
Configure the network for the newly installed environment: see [[Network configuration]].<br />
<br />
For [[Wireless configuration]], [[Help:Reading#Installation of packages|install]] the {{Pkg|iw}}, {{Pkg|wpa_supplicant}}, and {{Pkg|dialog}} packages, as well as needed [[Wireless#Installing driver/firmware|firmware packages]].<br />
<br />
=== Base Package Installation ===<br />
<br />
We've already included the {{Grp|base}} group which is, strictly speaking, all you need to boot a minimal Arch Linux system. At this stage, however, we can install some useful utilities (and Xorg or Wayland, etc.).<br />
<br />
# pacman -Syu base-devel btrfs-progs iw gptfdisk zsh vim terminus-font<br />
<br />
=== Initramfs ===<br />
<br />
Creating a new ''initramfs'' is usually not required, because [[mkinitcpio]] was run on installation of the {{Pkg|linux}} package with ''pacstrap''. However we'll need to make some changes to the hooks used on our system. Additionally, I switched over to using the systemd hooks in mkinitcpio, so that is largely what you'll see in my example below.<br />
<br />
I recommend making a backup of your {{ic|/etc/mkinitcpio.conf}} file first:<br />
<br />
# mv /etc/mkinitcpio.conf /etc/mkinitcpio.conf.orig<br />
<br />
and then editing a new file to match the following contents:<br />
<br />
{{bc|<nowiki><br />
MODULES=""<br />
BINARIES=""<br />
FILES=""<br />
HOOKS="base systemd sd-vconsole modconf keyboard block filesystems btrfs sd-encrypt fsck"<br />
</nowiki>}}<br />
<br />
Finally, recreate the initramfs image:<br />
<br />
# mkinitcpio -p linux<br />
<br />
=== Bootloader ===<br />
<br />
{{Warning|THIS SECTION IN PROGRESS}}<br />
<br />
=== Root password ===<br />
<br />
Set the root [[password]]:<br />
<br />
# passwd<br />
<br />
=== Leave the systemd-nspawn environment ===<br />
<br />
Issue a poweroff to exit the nspawned environment:<br />
<br />
# poweroff<br />
<br />
This will return you the Arch installer environment where you can wrap up.<br />
<br />
=== Legacy boot loader ===<br />
<br />
If your system is not UEFI and you need to use a legacy installer like grub, it will need to be installed from within an arch-chroot generated chroot, not the systemd-nspawn running container. An example of this would be (assuming that the drive of the new system is at /dev/sdb):<br />
<br />
# arch-chroot /mnt<br />
# grub-install $DRIVE<br />
# grub-mkconfig -o /boot/grub/grub.cfg<br />
# exit<br />
<br />
== Command Summary ==<br />
<br />
The following are all critical commands (exluded: the initial drive wipe which is optional). It assumes you have successfully brought up networking prior to starting this sequence.<br />
<br />
{{bc|<nowiki><br />
<br />
$DRIVE=/dev/DRIVEID<br />
<br />
sgdisk --zap-all $DRIVE<br />
<br />
sgdisk --clear \<br />
--new=1:0:+550MiB --typecode=1:ef00 --change-name=1:EFI \<br />
--new=2:0:+8GiB --typecode=2:8200 --change-name=2:cryptswap \<br />
--new=3:0:0 --typecode=2:8200 --change-name=3:cryptsystem \<br />
$DRIVE<br />
<br />
mkfs.fat -F32 -n EFI /dev/disk/by-partlabel/EFI<br />
<br />
cryptsetup luksFormat --align-payload=8192 -s 256 -c aes-xts-plain64 /dev/disk/by-partlabel/cryptsystem<br />
<br />
cryptsetup open /dev/disk/by-partlabel/cryptsystem system<br />
<br />
cryptsetup open --type plain --key-file /dev/urandom /dev/disk/by-partlabel/cryptswap swap<br />
<br />
mkswap -L swap /dev/mapper/swap<br />
<br />
swapon -L swap<br />
<br />
mkfs.btrfs --force --label system /dev/mapper/system<br />
<br />
o=defaults,x-mount.mkdir<br />
<br />
o_btrfs=$o,compress=lzo,ssd,noatime<br />
<br />
mount -t btrfs LABEL=system /mnt<br />
<br />
btrfs subvolume create /mnt/root<br />
<br />
btrfs subvolume create /mnt/home<br />
<br />
btrfs subvolume create /mnt/snapshots<br />
<br />
umount -R /mnt<br />
<br />
mount -t btrfs -o subvol=root,$o_btrfs LABEL=system /mnt<br />
<br />
mount -t btrfs -o subvol=home,$o_btrfs LABEL=system /mnt/home<br />
<br />
mount -t btrfs -o subvol=snapshots,$o_btrfs LABEL=system /mnt/.snapshots<br />
<br />
pacstrap /mnt base<br />
<br />
genfstab -L -p /mnt >> /mnt/etc/fstab<br />
<br />
sed -i "s+LABEL=swap+/dev/mapper/swap" /etc/fstab_labels<br />
<br />
systemd-nspawn -bD /mnt<br />
<br />
echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen<br />
<br />
locale-gen<br />
<br />
localectl set-locale LANG=en_US.UTF-8<br />
<br />
timedatectl set-ntp 1<br />
<br />
timedatectl set-timezone America/Los_Angeles<br />
<br />
hostnamectl set-hostname myhostname<br />
<br />
echo "127.0.1.1 myhostname.localdomain myhostname" >> /etc/hosts<br />
<br />
pacman -Syu base-devel btrfs-progs iw gptfdisk zsh vim terminus-font<br />
</nowiki>}}<br />
<br />
== Quick and Dirty ==<br />
<br />
{{Note|an extra example and may be moved to its own wiki page later}}<br />
<br />
This is the approximate process I follow if I want to bring up Arch on, say, an old laptop for a quick purpose built test machine, etc. It's not an install that I consider long term maintainable since rollbacks aren't implemented, nor is there any encryption, but it's a good example of how simple installation can be.<br />
<br />
{{bc|<nowiki><br />
$DRIVE=/dev/DRIVEID<br />
sgdisk --zap-all $DRIVE<br />
mkfs.btrfs -f $DRIVE<br />
mount -t btrfs $DRIVE /mnt<br />
pacstrap /mnt base<br />
systemd-nspawn -bD /mnt<br />
echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen<br />
locale-gen<br />
localectl set-locale LANG=en_US.UTF-8<br />
timedatectl set-ntp 1<br />
timedatectl set-timezone America/Los_Angeles<br />
hostnamectl set-hostname myhostname<br />
poweroff<br />
arch-chroot /mnt<br />
grub-install --root-directory=/mnt $DRIVE<br />
grub-mkconfig -o /mnt/boot/grub/grub.cfg<br />
exit<br />
reboot<br />
</nowiki>}}</div>Altercationhttps://wiki.archlinux.org/index.php?title=User:Altercation/Bullet_Proof_Arch_Install&diff=458642User:Altercation/Bullet Proof Arch Install2016-12-06T17:39:36Z<p>Altercation: /* Command Summary */</p>
<hr />
<div>This page is a summary of the current process I follow when installing Arch on a new laptop or desktop. My process varies over time, but this serves as my "state of the art" best practice recommendations. I'm open to feedback and suggestions for improvements.<br />
<br />
{{Note|This is entirely based on my own opinions and research. It is opinionated about the best way to do things given the current state of the kernel, hardware availability, and utilities, filesystems, etc. I will explain my rationale for specific choices and provide links to other sources of information (on the Arch wiki or external) where useful.}}<br />
<br />
== Objectives ==<br />
<br />
The goals of my standard "bullet proof" Arch Linux installation are:<br />
<br />
* Benefit from Arch's rolling release model while mitigating any risk of system corruption or data loss due to failed upgrades<br />
* Minimize risk due to hardware failure or total system loss (e.g. theft or physical destruction)<br />
* Make system rollbacks easy and procedural, using a standard setup and methodology for recovery of previous system (and user data) states<br />
<br />
=== Why not the Arch Install instructions? ===<br />
<br />
The [[Installation guide|Arch Linux installation instructions]] are an excellent, general starting point and you should read and understand them. That being said, they are designed to map to a very, very broad set of installation scenarios. I am interested in a very specific type of installation (daily use desktops and laptops in this article) and I have a strong set of opinions about the "right" or "best practice" way to set up my own working systems.<br />
<br />
These instructions, then, are much more prescriptive and have strong suggestions or directions about how (and why) one should use a particular method during Arch Linux installation.<br />
<br />
=== Key differences from the stock Arch install instructions ===<br />
<br />
How these instructions differ from the standard Arch guidance:<br />
<br />
* We are encrypting the entire system but not using LVM as is often recommended (see the encryption section below for details about why we are not using it).<br />
* I use labels and avoid UUIDs where possible to make switching to an alternate recovery drive easier.<br />
* I skip arch-chroot and simply boot the new system ('''not''' reboot, just boot) from within the install environment using {{Man|1|systemd-nspawn}} which enables the *ctl commands to work (and systemd services to be enabled properly without need for a system reboot)<br />
* I use the various systemd *ctl commands (hostnamectl, timedatectl, localectl, etc.) to configure the system<br />
* I use the systemd mkinitcpio hooks in lieu of the legacy hooks.<br />
* I use BTRFS exclusively for root and home partitions for its backup capabilities.<br />
* I recommend and use secure boot (but not with the Microsoft keys) to minimize risk due to the unavoidably unencrypted EFI partition.<br />
<br />
== Assumptions ==<br />
<br />
These instructions presuppose the following:<br />
<br />
* fairly new hardware (these instructions may work on older hardware, but there may be unusual issues that crop up... if you aren't comfortable handling those situations you should consider a more "traditional" Arch Linux install (e.g. using grub, LVM, ext4, etc.)<br />
* [[Unified Extensible Firmware Interface|UEFI support]] (BIOS system install is also possible with some modification of these instructions, but this has not yet been detailed here)<br />
* probably an [[Solid State Drives|SSD]].<br />
* some familiarity with Arch, or at least some experience with Linux, will help<br />
<br />
{{Warning|I am assuming you are going to single boot (not dual boot) and that you are '''willing to wipe all data from the install drive.''' If that is not the case, do not proceed with these instructions as following them '''will effectively destroy any data (and other operating systems) on the installation target drive.'''}}<br />
<br />
== Prerequisites ==<br />
<br />
You must have a recent copy of the Arch install USB. See [[:Category:Getting and installing Arch]] for general information and [[USB flash installation media]] for specific details on creating a USB Arch installation drive.<br />
<br />
You should also have a reasonable amount of time in which to complete the installation. Novice users will want to budget a couple hours. Experienced users will ''know'' to budget a couple hours.<br />
<br />
== Preparation ==<br />
<br />
=== Boot from USB Drive ===<br />
<br />
Boot your system from your prepared [[USB flash installation media|Arch Linux USB drive]]. It is important that you boot in EFI mode, not legacy BIOS compatibility mode. See the [[Unified Extensible Firmware Interface|UEFI]] article for more information about checking boot mode and ensuring you are booting using EFI.<br />
<br />
=== Bring up the network ===<br />
<br />
If you booted into a system with an ethernet cable plugged in, chances are you're up and running. If you need to use wireless instead, {{ic|wifi-menu}} will more often than not work without trouble. If those don't work, see [[Installation guide#Connect to the Internet|the Arch installation guide section on connecting to the internet]].<br />
<br />
=== Select Drive ===<br />
<br />
I like to use the [[Core utilities#lsblk|{{ic|1=lsblk}}]] command to bring up a quick list of the block devices on the system and identify existing partition structures and sizes, as well as mount points. If you don't already use it, I recommend [[Core utilities#lsblk|{{ic|1=lsblk}}]] when you need information on any given drive or partition. It's useful for polling UUIDs as well. For example, the following command gives you a clearly formatted summary of all block devices, their partition labels, filesystem lables, UUIDs and partition UUIDS: {{ic|lsblk -o +LABEL,PARTLABEL,UUID,PARTUUID}}<br />
<br />
In any case, the plain command without options should be enough to identify the drive you will install to (for example {{ic|1=/dev/sda}} or {{ic|1=/dev/nvme0n1}}:<br />
<br />
# lsblk<br />
<br />
=== Wipe Drive Securely (optional) ===<br />
<br />
While it is not necessary, given that this process will go through the trouble of encrypting the main system partition, it makes sense to do a secure wipe of the drive. This is more or less directly from [[Dm-crypt/Drive preparation#dm-crypt wipe on an empty disk or partition]].<br />
<br />
{{Warning|Be certain of your target device selection as we will be '''wiping this drive''' (either securely or, at minimum, destroying all existing partition data).}}<br />
<br />
First, create a temporary encrypted container the full disk ({{ic|sdX}}) to be encrypted, e.g. using default encryption parameters and a random key via the {{ic|--key-file /dev/{u}random}} option (see also [[Random number generation]]):<br />
<br />
# cryptsetup open --type plain /dev/sdXY container --key-file /dev/urandom<br />
<br />
{{Note|An interesting page addressing myths about /dev/urandom can be [http://www.2uo.de/myths-about-urandom/ found here]}}<br />
<br />
Second, check the container exists:<br />
<br />
{{hc|# fdisk -l|Disk /dev/mapper/container: XXXX MB, XXXXXXXXXX bytes<br />
...<br />
Disk /dev/mapper/container does not contain a valid partition table}}<br />
Wipe the container with zeros. A use of {{ic|1=if=/dev/urandom}} is '''not''' required as the encryption cipher itself generates randomness.<br />
{{hc|# dd <nowiki>if=/dev/zero of=/dev/mapper/container status=progress bs=1M</nowiki>|<br />
dd: writing to ‘/dev/mapper/container’: No space left on device}}<br />
<br />
{{Tip|<br />
* Using ''dd'' with the {{ic|1=bs=}} option, e.g. {{ic|1=bs=1M}} as above, is frequently used to increase disk throughput of the operation.<br />
* To perform a check of the operation, zero the partition before creating the wipe container. After the wipe command {{ic|blockdev --getsize64 ''/dev/mapper/container''}} can be used to get the exact container size as root. Now ''od'' can be used to spotcheck whether the wipe overwrote the zeroed sectors, e.g. {{ic|od -j ''containersize - blocksize''}} to view the wipe completed to the end.}}<br />
<br />
Finally, close the temporary container:<br />
<br />
# cryptsetup close container<br />
<br />
== Partition & Format Drive ==<br />
<br />
=== Understanding some basics about disks, partitions, and filesystems ===<br />
<br />
Think of your drive like a big empty building, no rooms. This is your plain physical drive (either a spinning platter drive or an SSD). Next imagine that to make it useful, we divide the building into apartments. In our analogy the apartments are '''partitions''' of the drive.<br />
<br />
Imagine also that there are a couple different standard methods of creating layout maps to the apartments. These plans are standardized so that the public services that have to access the building regularly (like the fire and police, for example) understand how to find the apartment entrances. In the world of partitioning, the equivalent is the "partition table scheme". The two common schemes are called "MBR" (Master Boot Record, older) and "GPT" (GUID Partition Table, newer). We will be using the new GPT scheme.<br />
<br />
Finally, imagine that the apartments are just empty shells. The act of building walls and laying out the functional structure of the apartments is equivalent to formatting our disk partitions with a filesystem. And just as different layouts may be more or less efficient, or have other different functional characteristics, so to filesystems have different attributes that make them useful in different ways.<br />
<br />
=== Our partition plans ===<br />
<br />
We will take our physical drive and divide it into three partitions. These partitions each serve a distinct purpose. All but the first and smallest, the EFI partition, will be encrypted. For security, if your system supports Secure Boot, you may choose to cryptographically sign the data stored on the EFI partition so that any tampering will be evident, despite the lack of encryption on that partition.<br />
<br />
{{Note|Again, we're assuming an UEFI installation (not legacy BIOS) and a GPT (not MBR) partition structure. If none of that made sense, best to start with the [[Partitioning]] article or do some test installs of Arch first. '''Partitioning is, in my opinion, one of the areas that is most confusing for the new Arch user.''' Additionally, there is a lot "received wisdom" and cargo-cult assumption making about how best to partition. Working through some of the "this is how it's always been done" tutorials isn't necessarily a bad thing... In many cases the way it has always been done has some sound reasoning behind it, despite being cargo-culted half the time. That being said, the method presented here is different from that in most of the Arch wiki partitioning methodologies.}}<br />
<br />
We will not be using LVM. You read a lot about LUKS and LVM and it all gets a bit complicated (LVM on LUKS, LUKS on LVM, etc.). LVM is a "logical volume manager" and abstracts physical devices (drives) into virtual devices, for easier management. It's a good idea but we will be using btrfs to effectively achieve the same results and really don't need the overhead of LVM.<br />
<br />
=== Partition Summary ===<br />
<br />
* 1: EFI - The UEFI 'bios" will look for this FAT32 formatted partition and either locate a default bootloader or will locate a specific EFI boot entry on it. This partition is by necessity not encrypted (unless the drive it is on has been encrypted as a "self encrypting drive")<br />
* 2: Swap - Used by Linux to swap out pages of memory from RAM to disk. Despite debate in this area, it is advisable to have at least some swap space, even it you are not planning on using hibernation on your machine. The Arch wiki is unfortunately rather too brief in its own [[Swap|swap article]] so I recommend the [https://docs.fedoraproject.org/en-US/Fedora/14/html/Storage_Administration_Guide/ch-swapspace.html Fedora documentation on swap] for a good overview on determining the right swap partition size.<br />
* 3: System - This will hold our root and home data. It will be formatted as BTRFS and will use subvolumes to manage snapshots of the current root and home contents.<br />
<br />
=== Visual overview of our partitions, filesystems, and contents ===<br />
<br />
This is a visual summary of our partions (inc. size information), encryption, filesystems, and a summary of the contents of each container.<br />
<br />
{| class="wikitable"<br />
| style="vertical-align: top; padding:1em" | '''Partition 1 (EFI)'''<br />
550MiB+<br />
{| style="border: 1px solid black; background: #DACEF2; margin: 1em;"<br />
! FAT32<br />
|-<br />
|kernel & initramfs<br />
(signed if using secure boot)<br />
|}<br />
| style="vertical-align: top; padding:1em" | '''Partition 2 (Swap)'''<br />
w/ Hibernate: Equal RAM,<br />
w/o Hibernate: min 8GB<br />
{| style="border: 1px solid black; background: #F2ECCE; margin: 1em;"<br />
|-<br />
! dm-crypt<br />
{| style="border: 1px solid black; background: #DACEF2; margin: 1em;"<br />
| SWAP<br />
|}<br />
|}<br />
| style="vertical-align: top; padding:1em" | '''Partition 3 (System)'''<br />
Remaining Space<br />
{| style="border: 1px solid black; background: #F2ECCE; margin: 1em;"<br />
|-<br />
! LUKS dm-crypt<br />
<br />
{| style="border: 1px solid black; background: #DACEF2; margin: 1em;"<br />
| BTRFS Top Level Subvolume<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Root Subvolume<br />
|}<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Home Subvolume<br />
|}<br />
<br />
{| style="border: 1px solid black; background: #E0CEF2; margin: 1em;"<br />
| BTRFS Snapshots Subvolume<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Root Snapshot Subvolume(s)<br />
|}<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Home Snapshot Subvolume(s)<br />
|}<br />
<br />
|}<br />
<br />
|}<br />
<br />
|}<br />
<br />
|}<br />
<br />
=== Partition Drive ===<br />
<br />
There are many utilities available for [[Partitioning]]. Because we are using Arch Linux and the command line doesn't hurt us (it makes us stronger) we will be using pure, non-interactive command line tools for this. Specifically, we will be using the utility [[Fdisk#Using_sgdisk|sgdisk]] from the {{Pkg|gptfdisk}} package. The [[Fdisk|fdisk]] utility now also supports GPT partitioned drives, so it would be an alternative. [[Fdisk#Using_sgdisk|sgdisk]] is available by default on the standard Arch install iso that you use to make your bootable USB drive.<br />
<br />
First, select the drive you will install to. Make sure you have selected the correct drive!. Again, a quick {{ic|lsblk}} will work here.<br />
<br />
# $DRIVE=/dev/DRIVEID<br />
<br />
(replace /dev/DRIVEID with the correct value, for example /dev/sda, /dev/nvme0n1, etc.)<br />
<br />
If you didn't securely wipe the drive already, it's worth "zapping" it using [[Fdisk#Using_sgdisk|sgdisk]] to remove any lingering legacy partition information. If you already wiped the drive you can skip this command (though it won't hurt to run it again).<br />
<br />
{{Warning|'''This command will also effectively erase the selected drive!'''}}<br />
<br />
# sgdisk --zap-all $DRIVE<br />
<br />
The following command will then create all three partitions in one go. '''It will also effectively erase the selected drive!'''<br />
<br />
# sgdisk --clear \<br />
--new=1:0:+550MiB --typecode=1:ef00 --change-name=1:EFI \<br />
--new=2:0:+8GiB --typecode=2:8200 --change-name=2:cryptswap \<br />
--new=3:0:0 --typecode=2:8200 --change-name=3:cryptsystem \<br />
$DRIVE<br />
<br />
It is worth noting that the "--change-name" values are, in this case, creating GPT "partition labels". You can subsequently see these by using the {{ic|lsblk -o +PARTLABEL}} command. It is good to use "EFI" for the efi partition. I am not aware of UEFI implementations that actively use the label for identification of the EFI partition, but it is possible that some do (UEFI bios implementations are not always consistent or to spec). The other two names are entirely "arbitrary". There is nothing special about calling them cryptswap and cryptsystem; they are simply good, clear names that remind us of the purpose of this partition and what it contains (for example, "cryptswap" suggests "this partition is for swap, and is encrypted").<br />
<br />
One final note about partition labels: we want them to be unique on your system. If for some reason there is already a GPT partition with the name EFI on another drive on your system, either change that partition name or use something besides "EFI" to avoid a namespace collision.<br />
<br />
Note also, that the backslashes at the end of each line can be omitted if you are writing the command on one long line instead. Those simply allow the splitting of a single command onto multiple lines.<br />
<br />
=== Format EFI Partition ===<br />
<br />
Next up: format the first (EFI) partition using the (required) FAT32 filesystem.<br />
<br />
# mksf.fat -F32 -n EFI /dev/disk/by-partlabel/EFI<br />
<br />
Note that we here make use of the partition label we just assigned. I prefer doing this since it simplifies scripts significantly for me and makes them, in my opinion, more readable.<br />
<br />
=== Encrypt System Partition ===<br />
<br />
Encrypt the main partition. Use a good passphrase. Note that the "--align-payload" value has been used as per [http://www.spinics.net/lists/dm-crypt/msg02421.html this suggestion/explanation] on the dm-crypt mailing list.<br />
<br />
Note also that I selected the encryption algorithm and key size using cryptsetup benchmark. See the [[Dm-crypt/Device_encryption]] article for more details.<br />
<br />
# cryptsetup luksFormat --align-payload=8192 -s 256 -c aes-xts-plain64 /dev/disk/by-partlabel/cryptsystem<br />
<br />
After creating the encrypted container, open it. Again, note the use of the partition label to identify the drive. Additionally, note that once we open this device we are giving it a name of "system." Thus "cryptsystem" is the encrypted system partition, while "system" is the name we are using once it has been opened in an unencrypted state. These names are arbitrary (Linux doesn't care what we use) but they help us keep things organized during this process.<br />
<br />
# cryptsetup open /dev/disk/by-partlabel/cryptsystem system<br />
<br />
=== Bring Up Encrypted Swap ===<br />
<br />
Finally we create encrypted swap. In this example we are not enabling hibernation. I will provide information on how to enable hibernation separately. Again, using partition labels to identify the partition and going from "cryptswap" to just "swap".<br />
<br />
We are not using LUKS here (which effectively makes dm-crypt easier to use). We're just using plain dm-crypt to encrypt the swap partition using a random key.<br />
<br />
# cryptsetup open --type plain --key-file /dev/urandom /dev/disk/by-partlabel/cryptswap swap<br />
# mkswap -L swap /dev/mapper/swap<br />
# swapon -L swap<br />
<br />
=== Create BTRFS Subvolumes ===<br />
<br />
Now on to the main attraction: creating our BTRFS subvolume structure. While BTRFS can be set up like any other filesystem (single command, just use the created file system directly), we're going to use the power of BTRFS to enable snapshotting our system state efficiently and rollbacks as necessary.<br />
<br />
First we create a top-level BTRFS subvolume. Note that the top-level entity in BTRFS nomenclature is still referred to as a '''sub'''volume, despite being at the top-level.<br />
<br />
We will create and mount this subvolume, create some new subvolumes inside it, and then switch to those subvolumes as our proper, mounted filesystems. Doing this will enable us to treat our root filesystem as a snapshotable object.<br />
<br />
Top-level subvolume creation.<br />
<br />
# mkfs.btrfs --force --label system /dev/mapper/system<br />
<br />
Temporarily mount our top-level volume for further subvolume creation. Note that the variable 'o' in this case is our default set of options for any given filesystem mount, while "o_btrfs" are those plus some options specific to btrfs. The default option "x-mount.mkdir" is a neat trick that allows us to skip the creation of directories for mountpoints (they will be created automatically). We assume /mnt as the standard mount point, as in a normal Arch Linux installation.<br />
<br />
# o=defaults,x-mount.mkdir<br />
# o_btrfs=$o,compress=lzo,ssd,noatime<br />
<br />
Note the use of our filesystem label to mount our subvolume. This is distinct from the partition labels used earlier. See the Arch wiki article on [[Persistent_block_device_naming]] for more information.<br />
<br />
# mount -t btrfs LABEL=system /mnt<br />
<br />
Now we create the subvolumes which will actually be mounted in our running system:<br />
<br />
# btrfs subvolume create /mnt/root<br />
# btrfs subvolume create /mnt/home<br />
# btrfs subvolume create /mnt/snapshots<br />
<br />
Then we unmount everything...<br />
<br />
# umount -R /mnt<br />
<br />
And remount just the subvolumes under our top-level subvolume (which remains unmounted unless we need to do "surgery" and rollback to a previous system system):<br />
<br />
# mount -t btrfs -o subvol=root,$o_btrfs LABEL=system /mnt<br />
<br />
Before mounting the home and snapshots subvolumes, let's walk through that command so we understand what it's doing:<br />
<br />
The 'mount -t btrfs' just specifies that our filesystem is of type BTRFS. This is often not necessary since mount will attempt to identify the filesystem type, but being explicit is often the best strategy with command line utilities, so we identify the type here.<br />
<br />
We use our previously defined mount options with the $o_btrfs variable and add the additional option "subvol=root" (separating it from our other defaults with a comma, of course). The next part of the command is "LABEL=system". Combined this reads as "mount the filesystem with the 'system' label, and use the 'root' subvolume within that".<br />
<br />
Finally, all this gets mounted at our install root, which in this case is "/mnt".<br />
<br />
Now let's pick back up and mount our home and snapshots subvolumes. Note that while the subvolume name is "snapshots", we will mount it at ".snapshots" (note dot prefix for the mount point). This will keep our root directory listing clean but will still make it available at a reasonable mount location.<br />
<br />
# mount -t btrfs -o subvol=home,$o_btrfs LABEL=system /mnt/home<br />
# mount -t btrfs -o subvol=snapshots,$o_btrfs LABEL=system /mnt/.snapshots<br />
<br />
It it worth noting that in each case we are telling mount to use the same filesystem, namely the one labeled "system". However in each case we are also telling it to look for a different subvolume in that filesystem (via the "subvol=" option).<br />
<br />
With this done, we can move on to installing the actual system.<br />
<br />
== Installation of Base Arch Linux System ==<br />
<br />
We are currently running off the Arch installer root filesystem. We will first use the 'pacstrap' utility to start our installation and then we will boot into our new minimal system using systemd-nspawn.<br />
<br />
=== Install base package group ===<br />
<br />
# pacstrap /mnt base<br />
<br />
=== fstab Generation and Modification ===<br />
<br />
{{Note|In a simpler, non encrypted configuration it is possible to skip making an fstab altogether due to a standard known as the [https://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/ Discoverable Partitions Spec]. However given the complexity of our encrypted, btrfs subvolume configuration, we require an fstab at this time. It is possible that in future we might feasibly do away with the fstab almost entirely in this setup (see the [https://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/#whataboutautomaticmountingofbtrfssubvolumestovarhomeandsoon 'What about automatic mounting of btrfs subvolumes'] section on that page).}}<br />
<br />
Create an [[fstab]] filesystem table file, using labels (-L) to identify the filesystems.<br />
<br />
# genfstab -L -p /mnt >> /mnt/etc/fstab<br />
<br />
I prefer to use labels as this makes the system more portable to a backup drive. You should end up with something that looks pretty close to this:<br />
<br />
{{hc|# cat /mnt/etc/fstab|<nowiki><br />
# /dev/mapper/system UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=system / btrfs rw,noatime,compress=lzo,ssd,space_cache,subvolid=257,subvol=/root,subvol=root 0 0<br />
<br />
# /dev/mapper/system UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=system /home btrfs rw,noatime,compress=lzo,ssd,space_cache,subvolid=258,subvol=/home,subvol=home 0 0<br />
<br />
# /dev/mapper/system UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=system /.snapshots btrfs rw,noatime,compress=lzo,ssd,space_cache,subvolid=259,subvol=/snapshots,subvol=snapshots 0 0<br />
<br />
# /dev/nvme0n1p1 UUID=xxxx-xxxx<br />
LABEL=EFI /boot/EFI vfat rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro 0 2<br />
<br />
# /dev/mapper/swap UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=swap none swap defaults 0 0<br />
</nowiki>}}<br />
<br />
There is one problem, however. Swap will not remount this way (the plain dm-crypt partition with a random key will not have a label when it is recreated on reboot). You will have to change that line from this:<br />
<br />
{{bc|<nowiki>LABEL=swap none swap defaults 0 0</nowiki>}}<br />
<br />
to this:<br />
<br />
{{bc|/dev/mapper/swap none swap defaults 0 0}}<br />
<br />
This will ensure that the mapped device is opened as swap successfully. The other lines may remain unchanged.<br />
<br />
==== Use {{ic|sed}} instead ====<br />
<br />
As a (scriptable) alternative to the manual editing of your {{ic|/etc/fstab}} you could use {{Man|1|sed}} to edit the file in place:<br />
<br />
# sed -i "s+LABEL=swap+/dev/mapper/swap" /etc/fstab_labels<br />
<br />
=== Boot into new system ===<br />
<br />
{{Warning|While this works, I am fairly certain I'll want to double check some things before declaring this step final. Specifically I want to consider some bind mounts and whether there is anything that should be r/w instead of r/o as is normal in a systemd-nspawn container.}}<br />
<br />
# systemd-nspawn -bD /mnt<br />
<br />
This will boot your new base Arch Linux system. After the standard boot messages scroll by you will be presented with a login (enter {{ic|root}} and hit enter to login).<br />
<br />
=== Generate and set locale ===<br />
<br />
Next, edit and uncomment your desired locale(s) from {{ic|/etc/locale.gen}}. We use {{ic|vi}} in the example below, but you could use a simpler editor such as {{ic|nano}} if you wish.<br />
<br />
{{hc|vi /etc/locale.gen|<nowiki><br />
...<br />
#en_PH.UTF-8 UTF-8<br />
#en_PH ISO-8859-1<br />
#en_SG.UTF-8 UTF-8<br />
#en_SG ISO-8859-1<br />
#en_US.UTF-8 UTF-8<br />
#en_US ISO-8859-1<br />
#en_ZA.UTF-8 UTF-8<br />
#en_ZA ISO-8859-1<br />
#en_ZM UTF-8<br />
...<br />
</nowiki>}}<br />
<br />
Changing it to (for en_US.UTF-8 as a locale in this example):<br />
<br />
{{bc|<nowiki><br />
...<br />
#en_PH.UTF-8 UTF-8<br />
#en_PH ISO-8859-1<br />
#en_SG.UTF-8 UTF-8<br />
#en_SG ISO-8859-1<br />
en_US.UTF-8 UTF-8<br />
#en_US ISO-8859-1<br />
#en_ZA.UTF-8 UTF-8<br />
#en_ZA ISO-8859-1<br />
#en_ZM UTF-8<br />
...<br />
</nowiki>}}<br />
<br />
Alternately one could simply append a known value to the {{ic|/etc/locale.gen}} file:<br />
<br />
# echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen<br />
<br />
After either method, one runs the {{ic|locale-gen}} command to generate the locale files:<br />
<br />
# locale-gen<br />
<br />
Finally we use {{Man|1|systemd-firstboot}} or {{Man|1|localectl}} to set the system locale. Each of these effectively does the same thing which is to simply write to {{ic|/etc/locale.conf}} (which can simply be edited directly as per standard Arch install instructions).<br />
<br />
==== With systemd-firstboot ====<br />
<br />
{{Man|1|systemd-firstboot}} will prompt us for selection from our generated locales. It will only work if there is no assigned system locale. If you wish to make changes afterward you can use {{Man|1|localectl}}<br />
<br />
# systemd-firstboot --prompt-locale<br />
<br />
==== With localectl ====<br />
<br />
This is an alternate to using {{ic|systemd-firstboot --prompt-locale}}. It may also be used subsequent to that command if further changes to the locale are desired.<br />
<br />
If you need a reminder of which locales have been installed (during this install or later during system changes), use {{ic|localectl list-locales}}:<br />
<br />
{{hc|<nowiki># localectl list-locales</nowiki>|en_US.UTF-8}}<br />
<br />
We then use {{ic|localectl set-locale}}:<br />
<br />
# localectl set-locale LANG=en_US.UTF-8<br />
<br />
=== Time and Date ===<br />
<br />
Unless you have a reason not to, we'll turn on NTP synchronization.<br />
<br />
# timedatectl set-ntp 1<br />
<br />
Then list timezones and pick one<br />
<br />
{{hc|<nowiki># timedatectl list-timezones</nowiki>|<nowiki><br />
...<br />
America/Kentucky/Louisville<br />
America/Kentucky/Monticello<br />
America/Kralendijk<br />
America/La_Paz<br />
America/Lima<br />
America/Los_Angeles<br />
America/Lower_Princes<br />
America/Maceio<br />
America/Managua<br />
America/Manaus<br />
America/Marigot<br />
America/Martinique<br />
America/Matamoros<br />
...<br />
</nowiki>}}<br />
# timedatectl set-timezone America/Los_Angeles<br />
<br />
=== Set hostname ===<br />
<br />
# hostnamectl set-hostname myhostname<br />
<br />
See the man page for {{Man|1|hostnamectl}} for other attributes that can be set. You might also add the hostname to {{Man|5|hosts}}:<br />
<br />
{{hc|/etc/hosts|<br />
127.0.0.1 localhost.localdomain localhost<br />
::1 localhost.localdomain localhost<br />
'''127.0.1.1 ''myhostname''.localdomain ''myhostname'''''<br />
}}<br />
<br />
Use {{ic|echo}} for a scriptable solution:<br />
<br />
# echo "127.0.1.1 myhostname.localdomain myhostname" >> /etc/hosts<br />
<br />
=== Network configuration ===<br />
<br />
Configure the network for the newly installed environment: see [[Network configuration]].<br />
<br />
For [[Wireless configuration]], [[Help:Reading#Installation of packages|install]] the {{Pkg|iw}}, {{Pkg|wpa_supplicant}}, and {{Pkg|dialog}} packages, as well as needed [[Wireless#Installing driver/firmware|firmware packages]].<br />
<br />
=== Base Package Installation ===<br />
<br />
We've already included the {{Grp|base}} group which is, strictly speaking, all you need to boot a minimal Arch Linux system. At this stage, however, we can install some useful utilities (and Xorg or Wayland, etc.).<br />
<br />
# pacman -Syu base-devel btrfs-progs iw gptfdisk zsh vim terminus-font<br />
<br />
=== Initramfs ===<br />
<br />
Creating a new ''initramfs'' is usually not required, because [[mkinitcpio]] was run on installation of the {{Pkg|linux}} package with ''pacstrap''. However we'll need to make some changes to the hooks used on our system. Additionally, I switched over to using the systemd hooks in mkinitcpio, so that is largely what you'll see in my example below.<br />
<br />
I recommend making a backup of your {{ic|/etc/mkinitcpio.conf}} file first:<br />
<br />
# mv /etc/mkinitcpio.conf /etc/mkinitcpio.conf.orig<br />
<br />
and then editing a new file to match the following contents:<br />
<br />
{{bc|<nowiki><br />
MODULES=""<br />
BINARIES=""<br />
FILES=""<br />
HOOKS="base systemd sd-vconsole modconf keyboard block filesystems btrfs sd-encrypt fsck"<br />
</nowiki>}}<br />
<br />
Finally, recreate the initramfs image:<br />
<br />
# mkinitcpio -p linux<br />
<br />
=== Bootloader ===<br />
<br />
{{Warning|THIS SECTION IN PROGRESS}}<br />
<br />
=== Root password ===<br />
<br />
Set the root [[password]]:<br />
<br />
# passwd<br />
<br />
=== Leave the systemd-nspawn environment ===<br />
<br />
Issue a poweroff to exit the nspawned environment:<br />
<br />
# poweroff<br />
<br />
This will return you the Arch installer environment where you can wrap up.<br />
<br />
=== Legacy boot loader ===<br />
<br />
If your system is not UEFI and you need to use a legacy installer like grub, it will need to be installed from within an arch-chroot generated chroot, not the systemd-nspawn running container. An example of this would be (assuming that the drive of the new system is at /dev/sdb):<br />
<br />
# arch-chroot /mnt<br />
# grub-install $DRIVE<br />
# grub-mkconfig -o /boot/grub/grub.cfg<br />
# exit<br />
<br />
== Command Summary ==<br />
<br />
The following are all critical commands (exluded: the initial drive wipe which is optional). It assumes you have successfully brought up networking prior to starting this sequence.<br />
<br />
{{bc|<nowiki><br />
<br />
$DRIVE=/dev/DRIVEID<br />
<br />
sgdisk --zap-all $DRIVE<br />
<br />
sgdisk --clear \<br />
--new=1:0:+550MiB --typecode=1:ef00 --change-name=1:EFI \<br />
--new=2:0:+8GiB --typecode=2:8200 --change-name=2:cryptswap \<br />
--new=3:0:0 --typecode=2:8200 --change-name=3:cryptsystem \<br />
$DRIVE<br />
<br />
mkfs.fat -F32 -n EFI /dev/disk/by-partlabel/EFI<br />
<br />
cryptsetup luksFormat --align-payload=8192 -s 256 -c aes-xts-plain64 /dev/disk/by-partlabel/cryptsystem<br />
<br />
cryptsetup open /dev/disk/by-partlabel/cryptsystem system<br />
<br />
cryptsetup open --type plain --key-file /dev/urandom /dev/disk/by-partlabel/cryptswap swap<br />
<br />
mkswap -L swap /dev/mapper/swap<br />
<br />
swapon -L swap<br />
<br />
mkfs.btrfs --force --label system /dev/mapper/system<br />
<br />
o=defaults,x-mount.mkdir<br />
<br />
o_btrfs=$o,compress=lzo,ssd,noatime<br />
<br />
mount -t btrfs LABEL=system /mnt<br />
<br />
btrfs subvolume create /mnt/root<br />
<br />
btrfs subvolume create /mnt/home<br />
<br />
btrfs subvolume create /mnt/snapshots<br />
<br />
umount -R /mnt<br />
<br />
mount -t btrfs -o subvol=root,$o_btrfs LABEL=system /mnt<br />
<br />
mount -t btrfs -o subvol=home,$o_btrfs LABEL=system /mnt/home<br />
<br />
mount -t btrfs -o subvol=snapshots,$o_btrfs LABEL=system /mnt/.snapshots<br />
<br />
pacstrap /mnt base<br />
<br />
genfstab -L -p /mnt >> /mnt/etc/fstab<br />
<br />
sed -i "s+LABEL=swap+/dev/mapper/swap" /etc/fstab_labels<br />
<br />
systemd-nspawn -bD /mnt<br />
<br />
echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen<br />
<br />
locale-gen<br />
<br />
localectl set-locale LANG=en_US.UTF-8<br />
<br />
timedatectl set-ntp 1<br />
<br />
timedatectl set-timezone America/Los_Angeles<br />
<br />
hostnamectl set-hostname myhostname<br />
<br />
echo "127.0.1.1 myhostname.localdomain myhostname" >> /etc/hosts<br />
<br />
pacman -Syu base-devel btrfs-progs iw gptfdisk zsh vim terminus-font<br />
</nowiki>}}<br />
<br />
== Quick and Dirty ==<br />
<br />
{{Note|an extra example and may be moved to its own wiki page later}}<br />
<br />
This is the approximate process I follow if I want to bring up Arch on, say, an old laptop for a quick purpose built test machine, etc. It's not an install that I consider long term maintainable since rollbacks aren't implemented, nor is there any encryption, but it's a good example of how simple installation can be.<br />
<br />
{{bc|<nowiki><br />
$DRIVE=/dev/DRIVEID<br />
sgdisk --zap-all $DRIVE<br />
mkfs.btrfs -f $DRIVE<br />
mount -t btrfs $DRIVE /mnt<br />
pacstrap /mnt base<br />
systemd-nspawn -bD /mnt<br />
echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen<br />
locale-gen<br />
localectl set-locale LANG=en_US.UTF-8<br />
timedatectl set-ntp 1<br />
timedatectl set-timezone America/Los_Angeles<br />
hostnamectl set-hostname myhostname<br />
poweroff<br />
arch-chroot /mnt<br />
grub-install --root-directory=/mnt $DRIVE<br />
grub-mkconfig -o /mnt/boot/grub/grub.cfg<br />
exit<br />
reboot<br />
</nowiki>}}</div>Altercationhttps://wiki.archlinux.org/index.php?title=User:Altercation/Bullet_Proof_Arch_Install&diff=458571User:Altercation/Bullet Proof Arch Install2016-12-06T00:05:52Z<p>Altercation: /* Boot into new system */</p>
<hr />
<div>This page is a summary of the current process I follow when installing Arch on a new laptop or desktop. My process varies over time, but this serves as my "state of the art" best practice recommendations. I'm open to feedback and suggestions for improvements.<br />
<br />
{{Note|This is entirely based on my own opinions and research. It is opinionated about the best way to do things given the current state of the kernel, hardware availability, and utilities, filesystems, etc. I will explain my rationale for specific choices and provide links to other sources of information (on the Arch wiki or external) where useful.}}<br />
<br />
== Objectives ==<br />
<br />
The goals of my standard "bullet proof" Arch Linux installation are:<br />
<br />
* Benefit from Arch's rolling release model while mitigating any risk of system corruption or data loss due to failed upgrades<br />
* Minimize risk due to hardware failure or total system loss (e.g. theft or physical destruction)<br />
* Make system rollbacks easy and procedural, using a standard setup and methodology for recovery of previous system (and user data) states<br />
<br />
=== Why not the Arch Install instructions? ===<br />
<br />
The [[Installation guide|Arch Linux installation instructions]] are an excellent, general starting point and you should read and understand them. That being said, they are designed to map to a very, very broad set of installation scenarios. I am interested in a very specific type of installation (daily use desktops and laptops in this article) and I have a strong set of opinions about the "right" or "best practice" way to set up my own working systems.<br />
<br />
These instructions, then, are much more prescriptive and have strong suggestions or directions about how (and why) one should use a particular method during Arch Linux installation.<br />
<br />
=== Key differences from the stock Arch install instructions ===<br />
<br />
How these instructions differ from the standard Arch guidance:<br />
<br />
* We are encrypting the entire system but not using LVM as is often recommended (see the encryption section below for details about why we are not using it).<br />
* I use labels and avoid UUIDs where possible to make switching to an alternate recovery drive easier.<br />
* I skip arch-chroot and simply boot the new system ('''not''' reboot, just boot) from within the install environment using {{Man|1|systemd-nspawn}} which enables the *ctl commands to work (and systemd services to be enabled properly without need for a system reboot)<br />
* I use the various systemd *ctl commands (hostnamectl, timedatectl, localectl, etc.) to configure the system<br />
* I use the systemd mkinitcpio hooks in lieu of the legacy hooks.<br />
* I use BTRFS exclusively for root and home partitions for its backup capabilities.<br />
* I recommend and use secure boot (but not with the Microsoft keys) to minimize risk due to the unavoidably unencrypted EFI partition.<br />
<br />
== Assumptions ==<br />
<br />
These instructions presuppose the following:<br />
<br />
* fairly new hardware (these instructions may work on older hardware, but there may be unusual issues that crop up... if you aren't comfortable handling those situations you should consider a more "traditional" Arch Linux install (e.g. using grub, LVM, ext4, etc.)<br />
* [[Unified Extensible Firmware Interface|UEFI support]] (BIOS system install is also possible with some modification of these instructions, but this has not yet been detailed here)<br />
* probably an [[Solid State Drives|SSD]].<br />
* some familiarity with Arch, or at least some experience with Linux, will help<br />
<br />
{{Warning|I am assuming you are going to single boot (not dual boot) and that you are '''willing to wipe all data from the install drive.''' If that is not the case, do not proceed with these instructions as following them '''will effectively destroy any data (and other operating systems) on the installation target drive.'''}}<br />
<br />
== Prerequisites ==<br />
<br />
You must have a recent copy of the Arch install USB. See [[:Category:Getting and installing Arch]] for general information and [[USB flash installation media]] for specific details on creating a USB Arch installation drive.<br />
<br />
You should also have a reasonable amount of time in which to complete the installation. Novice users will want to budget a couple hours. Experienced users will ''know'' to budget a couple hours.<br />
<br />
== Preparation ==<br />
<br />
=== Boot from USB Drive ===<br />
<br />
Boot your system from your prepared [[USB flash installation media|Arch Linux USB drive]]. It is important that you boot in EFI mode, not legacy BIOS compatibility mode. See the [[Unified Extensible Firmware Interface|UEFI]] article for more information about checking boot mode and ensuring you are booting using EFI.<br />
<br />
=== Bring up the network ===<br />
<br />
If you booted into a system with an ethernet cable plugged in, chances are you're up and running. If you need to use wireless instead, {{ic|wifi-menu}} will more often than not work without trouble. If those don't work, see [[Installation guide#Connect to the Internet|the Arch installation guide section on connecting to the internet]].<br />
<br />
=== Select Drive ===<br />
<br />
I like to use the [[Core utilities#lsblk|{{ic|1=lsblk}}]] command to bring up a quick list of the block devices on the system and identify existing partition structures and sizes, as well as mount points. If you don't already use it, I recommend [[Core utilities#lsblk|{{ic|1=lsblk}}]] when you need information on any given drive or partition. It's useful for polling UUIDs as well. For example, the following command gives you a clearly formatted summary of all block devices, their partition labels, filesystem lables, UUIDs and partition UUIDS: {{ic|lsblk -o +LABEL,PARTLABEL,UUID,PARTUUID}}<br />
<br />
In any case, the plain command without options should be enough to identify the drive you will install to (for example {{ic|1=/dev/sda}} or {{ic|1=/dev/nvme0n1}}:<br />
<br />
# lsblk<br />
<br />
=== Wipe Drive Securely (optional) ===<br />
<br />
While it is not necessary, given that this process will go through the trouble of encrypting the main system partition, it makes sense to do a secure wipe of the drive. This is more or less directly from [[Dm-crypt/Drive preparation#dm-crypt wipe on an empty disk or partition]].<br />
<br />
{{Warning|Be certain of your target device selection as we will be '''wiping this drive''' (either securely or, at minimum, destroying all existing partition data).}}<br />
<br />
First, create a temporary encrypted container the full disk ({{ic|sdX}}) to be encrypted, e.g. using default encryption parameters and a random key via the {{ic|--key-file /dev/{u}random}} option (see also [[Random number generation]]):<br />
<br />
# cryptsetup open --type plain /dev/sdXY container --key-file /dev/urandom<br />
<br />
{{Note|An interesting page addressing myths about /dev/urandom can be [http://www.2uo.de/myths-about-urandom/ found here]}}<br />
<br />
Second, check the container exists:<br />
<br />
{{hc|# fdisk -l|Disk /dev/mapper/container: XXXX MB, XXXXXXXXXX bytes<br />
...<br />
Disk /dev/mapper/container does not contain a valid partition table}}<br />
Wipe the container with zeros. A use of {{ic|1=if=/dev/urandom}} is '''not''' required as the encryption cipher itself generates randomness.<br />
{{hc|# dd <nowiki>if=/dev/zero of=/dev/mapper/container status=progress bs=1M</nowiki>|<br />
dd: writing to ‘/dev/mapper/container’: No space left on device}}<br />
<br />
{{Tip|<br />
* Using ''dd'' with the {{ic|1=bs=}} option, e.g. {{ic|1=bs=1M}} as above, is frequently used to increase disk throughput of the operation.<br />
* To perform a check of the operation, zero the partition before creating the wipe container. After the wipe command {{ic|blockdev --getsize64 ''/dev/mapper/container''}} can be used to get the exact container size as root. Now ''od'' can be used to spotcheck whether the wipe overwrote the zeroed sectors, e.g. {{ic|od -j ''containersize - blocksize''}} to view the wipe completed to the end.}}<br />
<br />
Finally, close the temporary container:<br />
<br />
# cryptsetup close container<br />
<br />
== Partition & Format Drive ==<br />
<br />
=== Understanding some basics about disks, partitions, and filesystems ===<br />
<br />
Think of your drive like a big empty building, no rooms. This is your plain physical drive (either a spinning platter drive or an SSD). Next imagine that to make it useful, we divide the building into apartments. In our analogy the apartments are '''partitions''' of the drive.<br />
<br />
Imagine also that there are a couple different standard methods of creating layout maps to the apartments. These plans are standardized so that the public services that have to access the building regularly (like the fire and police, for example) understand how to find the apartment entrances. In the world of partitioning, the equivalent is the "partition table scheme". The two common schemes are called "MBR" (Master Boot Record, older) and "GPT" (GUID Partition Table, newer). We will be using the new GPT scheme.<br />
<br />
Finally, imagine that the apartments are just empty shells. The act of building walls and laying out the functional structure of the apartments is equivalent to formatting our disk partitions with a filesystem. And just as different layouts may be more or less efficient, or have other different functional characteristics, so to filesystems have different attributes that make them useful in different ways.<br />
<br />
=== Our partition plans ===<br />
<br />
We will take our physical drive and divide it into three partitions. These partitions each serve a distinct purpose. All but the first and smallest, the EFI partition, will be encrypted. For security, if your system supports Secure Boot, you may choose to cryptographically sign the data stored on the EFI partition so that any tampering will be evident, despite the lack of encryption on that partition.<br />
<br />
{{Note|Again, we're assuming an UEFI installation (not legacy BIOS) and a GPT (not MBR) partition structure. If none of that made sense, best to start with the [[Partitioning]] article or do some test installs of Arch first. '''Partitioning is, in my opinion, one of the areas that is most confusing for the new Arch user.''' Additionally, there is a lot "received wisdom" and cargo-cult assumption making about how best to partition. Working through some of the "this is how it's always been done" tutorials isn't necessarily a bad thing... In many cases the way it has always been done has some sound reasoning behind it, despite being cargo-culted half the time. That being said, the method presented here is different from that in most of the Arch wiki partitioning methodologies.}}<br />
<br />
We will not be using LVM. You read a lot about LUKS and LVM and it all gets a bit complicated (LVM on LUKS, LUKS on LVM, etc.). LVM is a "logical volume manager" and abstracts physical devices (drives) into virtual devices, for easier management. It's a good idea but we will be using btrfs to effectively achieve the same results and really don't need the overhead of LVM.<br />
<br />
=== Partition Summary ===<br />
<br />
* 1: EFI - The UEFI 'bios" will look for this FAT32 formatted partition and either locate a default bootloader or will locate a specific EFI boot entry on it. This partition is by necessity not encrypted (unless the drive it is on has been encrypted as a "self encrypting drive")<br />
* 2: Swap - Used by Linux to swap out pages of memory from RAM to disk. Despite debate in this area, it is advisable to have at least some swap space, even it you are not planning on using hibernation on your machine. The Arch wiki is unfortunately rather too brief in its own [[Swap|swap article]] so I recommend the [https://docs.fedoraproject.org/en-US/Fedora/14/html/Storage_Administration_Guide/ch-swapspace.html Fedora documentation on swap] for a good overview on determining the right swap partition size.<br />
* 3: System - This will hold our root and home data. It will be formatted as BTRFS and will use subvolumes to manage snapshots of the current root and home contents.<br />
<br />
=== Visual overview of our partitions, filesystems, and contents ===<br />
<br />
This is a visual summary of our partions (inc. size information), encryption, filesystems, and a summary of the contents of each container.<br />
<br />
{| class="wikitable"<br />
| style="vertical-align: top; padding:1em" | '''Partition 1 (EFI)'''<br />
550MiB+<br />
{| style="border: 1px solid black; background: #DACEF2; margin: 1em;"<br />
! FAT32<br />
|-<br />
|kernel & initramfs<br />
(signed if using secure boot)<br />
|}<br />
| style="vertical-align: top; padding:1em" | '''Partition 2 (Swap)'''<br />
w/ Hibernate: Equal RAM,<br />
w/o Hibernate: min 8GB<br />
{| style="border: 1px solid black; background: #F2ECCE; margin: 1em;"<br />
|-<br />
! dm-crypt<br />
{| style="border: 1px solid black; background: #DACEF2; margin: 1em;"<br />
| SWAP<br />
|}<br />
|}<br />
| style="vertical-align: top; padding:1em" | '''Partition 3 (System)'''<br />
Remaining Space<br />
{| style="border: 1px solid black; background: #F2ECCE; margin: 1em;"<br />
|-<br />
! LUKS dm-crypt<br />
<br />
{| style="border: 1px solid black; background: #DACEF2; margin: 1em;"<br />
| BTRFS Top Level Subvolume<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Root Subvolume<br />
|}<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Home Subvolume<br />
|}<br />
<br />
{| style="border: 1px solid black; background: #E0CEF2; margin: 1em;"<br />
| BTRFS Snapshots Subvolume<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Root Snapshot Subvolume(s)<br />
|}<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Home Snapshot Subvolume(s)<br />
|}<br />
<br />
|}<br />
<br />
|}<br />
<br />
|}<br />
<br />
|}<br />
<br />
=== Partition Drive ===<br />
<br />
There are many utilities available for [[Partitioning]]. Because we are using Arch Linux and the command line doesn't hurt us (it makes us stronger) we will be using pure, non-interactive command line tools for this. Specifically, we will be using the utility [[Fdisk#Using_sgdisk|sgdisk]] from the {{Pkg|gptfdisk}} package. The [[Fdisk|fdisk]] utility now also supports GPT partitioned drives, so it would be an alternative. [[Fdisk#Using_sgdisk|sgdisk]] is available by default on the standard Arch install iso that you use to make your bootable USB drive.<br />
<br />
First, select the drive you will install to. Make sure you have selected the correct drive!. Again, a quick {{ic|lsblk}} will work here.<br />
<br />
# $DRIVE=/dev/DRIVEID<br />
<br />
(replace /dev/DRIVEID with the correct value, for example /dev/sda, /dev/nvme0n1, etc.)<br />
<br />
If you didn't securely wipe the drive already, it's worth "zapping" it using [[Fdisk#Using_sgdisk|sgdisk]] to remove any lingering legacy partition information. If you already wiped the drive you can skip this command (though it won't hurt to run it again).<br />
<br />
{{Warning|'''This command will also effectively erase the selected drive!'''}}<br />
<br />
# sgdisk --zap-all $DRIVE<br />
<br />
The following command will then create all three partitions in one go. '''It will also effectively erase the selected drive!'''<br />
<br />
# sgdisk --clear \<br />
--new=1:0:+550MiB --typecode=1:ef00 --change-name=1:EFI \<br />
--new=2:0:+8GiB --typecode=2:8200 --change-name=2:cryptswap \<br />
--new=3:0:0 --typecode=2:8200 --change-name=3:cryptsystem \<br />
$DRIVE<br />
<br />
It is worth noting that the "--change-name" values are, in this case, creating GPT "partition labels". You can subsequently see these by using the {{ic|lsblk -o +PARTLABEL}} command. It is good to use "EFI" for the efi partition. I am not aware of UEFI implementations that actively use the label for identification of the EFI partition, but it is possible that some do (UEFI bios implementations are not always consistent or to spec). The other two names are entirely "arbitrary". There is nothing special about calling them cryptswap and cryptsystem; they are simply good, clear names that remind us of the purpose of this partition and what it contains (for example, "cryptswap" suggests "this partition is for swap, and is encrypted").<br />
<br />
One final note about partition labels: we want them to be unique on your system. If for some reason there is already a GPT partition with the name EFI on another drive on your system, either change that partition name or use something besides "EFI" to avoid a namespace collision.<br />
<br />
Note also, that the backslashes at the end of each line can be omitted if you are writing the command on one long line instead. Those simply allow the splitting of a single command onto multiple lines.<br />
<br />
=== Format EFI Partition ===<br />
<br />
Next up: format the first (EFI) partition using the (required) FAT32 filesystem.<br />
<br />
# mksf.fat -F32 -n EFI /dev/disk/by-partlabel/EFI<br />
<br />
Note that we here make use of the partition label we just assigned. I prefer doing this since it simplifies scripts significantly for me and makes them, in my opinion, more readable.<br />
<br />
=== Encrypt System Partition ===<br />
<br />
Encrypt the main partition. Use a good passphrase. Note that the "--align-payload" value has been used as per [http://www.spinics.net/lists/dm-crypt/msg02421.html this suggestion/explanation] on the dm-crypt mailing list.<br />
<br />
Note also that I selected the encryption algorithm and key size using cryptsetup benchmark. See the [[Dm-crypt/Device_encryption]] article for more details.<br />
<br />
# cryptsetup luksFormat --align-payload=8192 -s 256 -c aes-xts-plain64 /dev/disk/by-partlabel/cryptsystem<br />
<br />
After creating the encrypted container, open it. Again, note the use of the partition label to identify the drive. Additionally, note that once we open this device we are giving it a name of "system." Thus "cryptsystem" is the encrypted system partition, while "system" is the name we are using once it has been opened in an unencrypted state. These names are arbitrary (Linux doesn't care what we use) but they help us keep things organized during this process.<br />
<br />
# cryptsetup open /dev/disk/by-partlabel/cryptsystem system<br />
<br />
=== Bring Up Encrypted Swap ===<br />
<br />
Finally we create encrypted swap. In this example we are not enabling hibernation. I will provide information on how to enable hibernation separately. Again, using partition labels to identify the partition and going from "cryptswap" to just "swap".<br />
<br />
We are not using LUKS here (which effectively makes dm-crypt easier to use). We're just using plain dm-crypt to encrypt the swap partition using a random key.<br />
<br />
# cryptsetup open --type plain --key-file /dev/urandom /dev/disk/by-partlabel/cryptswap swap<br />
# mkswap -L swap /dev/mapper/swap<br />
# swapon -L swap<br />
<br />
=== Create BTRFS Subvolumes ===<br />
<br />
Now on to the main attraction: creating our BTRFS subvolume structure. While BTRFS can be set up like any other filesystem (single command, just use the created file system directly), we're going to use the power of BTRFS to enable snapshotting our system state efficiently and rollbacks as necessary.<br />
<br />
First we create a top-level BTRFS subvolume. Note that the top-level entity in BTRFS nomenclature is still referred to as a '''sub'''volume, despite being at the top-level.<br />
<br />
We will create and mount this subvolume, create some new subvolumes inside it, and then switch to those subvolumes as our proper, mounted filesystems. Doing this will enable us to treat our root filesystem as a snapshotable object.<br />
<br />
Top-level subvolume creation.<br />
<br />
# mkfs.btrfs --force --label system /dev/mapper/system<br />
<br />
Temporarily mount our top-level volume for further subvolume creation. Note that the variable 'o' in this case is our default set of options for any given filesystem mount, while "o_btrfs" are those plus some options specific to btrfs. The default option "x-mount.mkdir" is a neat trick that allows us to skip the creation of directories for mountpoints (they will be created automatically). We assume /mnt as the standard mount point, as in a normal Arch Linux installation.<br />
<br />
# o=defaults,x-mount.mkdir<br />
# o_btrfs=$o,compress=lzo,ssd,noatime<br />
<br />
Note the use of our filesystem label to mount our subvolume. This is distinct from the partition labels used earlier. See the Arch wiki article on [[Persistent_block_device_naming]] for more information.<br />
<br />
# mount -t btrfs LABEL=system /mnt<br />
<br />
Now we create the subvolumes which will actually be mounted in our running system:<br />
<br />
# btrfs subvolume create /mnt/root<br />
# btrfs subvolume create /mnt/home<br />
# btrfs subvolume create /mnt/snapshots<br />
<br />
Then we unmount everything...<br />
<br />
# umount -R /mnt<br />
<br />
And remount just the subvolumes under our top-level subvolume (which remains unmounted unless we need to do "surgery" and rollback to a previous system system):<br />
<br />
# mount -t btrfs -o subvol=root,$o_btrfs LABEL=system /mnt<br />
<br />
Before mounting the home and snapshots subvolumes, let's walk through that command so we understand what it's doing:<br />
<br />
The 'mount -t btrfs' just specifies that our filesystem is of type BTRFS. This is often not necessary since mount will attempt to identify the filesystem type, but being explicit is often the best strategy with command line utilities, so we identify the type here.<br />
<br />
We use our previously defined mount options with the $o_btrfs variable and add the additional option "subvol=root" (separating it from our other defaults with a comma, of course). The next part of the command is "LABEL=system". Combined this reads as "mount the filesystem with the 'system' label, and use the 'root' subvolume within that".<br />
<br />
Finally, all this gets mounted at our install root, which in this case is "/mnt".<br />
<br />
Now let's pick back up and mount our home and snapshots subvolumes. Note that while the subvolume name is "snapshots", we will mount it at ".snapshots" (note dot prefix for the mount point). This will keep our root directory listing clean but will still make it available at a reasonable mount location.<br />
<br />
# mount -t btrfs -o subvol=home,$o_btrfs LABEL=system /mnt/home<br />
# mount -t btrfs -o subvol=snapshots,$o_btrfs LABEL=system /mnt/.snapshots<br />
<br />
It it worth noting that in each case we are telling mount to use the same filesystem, namely the one labeled "system". However in each case we are also telling it to look for a different subvolume in that filesystem (via the "subvol=" option).<br />
<br />
With this done, we can move on to installing the actual system.<br />
<br />
== Installation of Base Arch Linux System ==<br />
<br />
We are currently running off the Arch installer root filesystem. We will first use the 'pacstrap' utility to start our installation and then we will boot into our new minimal system using systemd-nspawn.<br />
<br />
=== Install base package group ===<br />
<br />
# pacstrap /mnt base<br />
<br />
=== fstab Generation and Modification ===<br />
<br />
{{Note|In a simpler, non encrypted configuration it is possible to skip making an fstab altogether due to a standard known as the [https://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/ Discoverable Partitions Spec]. However given the complexity of our encrypted, btrfs subvolume configuration, we require an fstab at this time. It is possible that in future we might feasibly do away with the fstab almost entirely in this setup (see the [https://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/#whataboutautomaticmountingofbtrfssubvolumestovarhomeandsoon 'What about automatic mounting of btrfs subvolumes'] section on that page).}}<br />
<br />
Create an [[fstab]] filesystem table file, using labels (-L) to identify the filesystems.<br />
<br />
# genfstab -L -p /mnt >> /mnt/etc/fstab<br />
<br />
I prefer to use labels as this makes the system more portable to a backup drive. You should end up with something that looks pretty close to this:<br />
<br />
{{hc|# cat /mnt/etc/fstab|<nowiki><br />
# /dev/mapper/system UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=system / btrfs rw,noatime,compress=lzo,ssd,space_cache,subvolid=257,subvol=/root,subvol=root 0 0<br />
<br />
# /dev/mapper/system UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=system /home btrfs rw,noatime,compress=lzo,ssd,space_cache,subvolid=258,subvol=/home,subvol=home 0 0<br />
<br />
# /dev/mapper/system UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=system /.snapshots btrfs rw,noatime,compress=lzo,ssd,space_cache,subvolid=259,subvol=/snapshots,subvol=snapshots 0 0<br />
<br />
# /dev/nvme0n1p1 UUID=xxxx-xxxx<br />
LABEL=EFI /boot/EFI vfat rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro 0 2<br />
<br />
# /dev/mapper/swap UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=swap none swap defaults 0 0<br />
</nowiki>}}<br />
<br />
There is one problem, however. Swap will not remount this way (the plain dm-crypt partition with a random key will not have a label when it is recreated on reboot). You will have to change that line from this:<br />
<br />
{{bc|<nowiki>LABEL=swap none swap defaults 0 0</nowiki>}}<br />
<br />
to this:<br />
<br />
{{bc|/dev/mapper/swap none swap defaults 0 0}}<br />
<br />
This will ensure that the mapped device is opened as swap successfully. The other lines may remain unchanged.<br />
<br />
==== Use {{ic|sed}} instead ====<br />
<br />
As a (scriptable) alternative to the manual editing of your {{ic|/etc/fstab}} you could use {{Man|1|sed}} to edit the file in place:<br />
<br />
# sed -i "s+LABEL=swap+/dev/mapper/swap" /etc/fstab_labels<br />
<br />
=== Boot into new system ===<br />
<br />
{{Warning|While this works, I am fairly certain I'll want to double check some things before declaring this step final. Specifically I want to consider some bind mounts and whether there is anything that should be r/w instead of r/o as is normal in a systemd-nspawn container.}}<br />
<br />
# systemd-nspawn -bD /mnt<br />
<br />
This will boot your new base Arch Linux system. After the standard boot messages scroll by you will be presented with a login (enter {{ic|root}} and hit enter to login).<br />
<br />
=== Generate and set locale ===<br />
<br />
Next, edit and uncomment your desired locale(s) from {{ic|/etc/locale.gen}}. We use {{ic|vi}} in the example below, but you could use a simpler editor such as {{ic|nano}} if you wish.<br />
<br />
{{hc|vi /etc/locale.gen|<nowiki><br />
...<br />
#en_PH.UTF-8 UTF-8<br />
#en_PH ISO-8859-1<br />
#en_SG.UTF-8 UTF-8<br />
#en_SG ISO-8859-1<br />
#en_US.UTF-8 UTF-8<br />
#en_US ISO-8859-1<br />
#en_ZA.UTF-8 UTF-8<br />
#en_ZA ISO-8859-1<br />
#en_ZM UTF-8<br />
...<br />
</nowiki>}}<br />
<br />
Changing it to (for en_US.UTF-8 as a locale in this example):<br />
<br />
{{bc|<nowiki><br />
...<br />
#en_PH.UTF-8 UTF-8<br />
#en_PH ISO-8859-1<br />
#en_SG.UTF-8 UTF-8<br />
#en_SG ISO-8859-1<br />
en_US.UTF-8 UTF-8<br />
#en_US ISO-8859-1<br />
#en_ZA.UTF-8 UTF-8<br />
#en_ZA ISO-8859-1<br />
#en_ZM UTF-8<br />
...<br />
</nowiki>}}<br />
<br />
Alternately one could simply append a known value to the {{ic|/etc/locale.gen}} file:<br />
<br />
# echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen<br />
<br />
After either method, one runs the {{ic|locale-gen}} command to generate the locale files:<br />
<br />
# locale-gen<br />
<br />
Finally we use {{Man|1|systemd-firstboot}} or {{Man|1|localectl}} to set the system locale. Each of these effectively does the same thing which is to simply write to {{ic|/etc/locale.conf}} (which can simply be edited directly as per standard Arch install instructions).<br />
<br />
==== With systemd-firstboot ====<br />
<br />
{{Man|1|systemd-firstboot}} will prompt us for selection from our generated locales. It will only work if there is no assigned system locale. If you wish to make changes afterward you can use {{Man|1|localectl}}<br />
<br />
# systemd-firstboot --prompt-locale<br />
<br />
==== With localectl ====<br />
<br />
This is an alternate to using {{ic|systemd-firstboot --prompt-locale}}. It may also be used subsequent to that command if further changes to the locale are desired.<br />
<br />
If you need a reminder of which locales have been installed (during this install or later during system changes), use {{ic|localectl list-locales}}:<br />
<br />
{{hc|<nowiki># localectl list-locales</nowiki>|en_US.UTF-8}}<br />
<br />
We then use {{ic|localectl set-locale}}:<br />
<br />
# localectl set-locale LANG=en_US.UTF-8<br />
<br />
=== Time and Date ===<br />
<br />
Unless you have a reason not to, we'll turn on NTP synchronization.<br />
<br />
# timedatectl set-ntp 1<br />
<br />
Then list timezones and pick one<br />
<br />
{{hc|<nowiki># timedatectl list-timezones</nowiki>|<nowiki><br />
...<br />
America/Kentucky/Louisville<br />
America/Kentucky/Monticello<br />
America/Kralendijk<br />
America/La_Paz<br />
America/Lima<br />
America/Los_Angeles<br />
America/Lower_Princes<br />
America/Maceio<br />
America/Managua<br />
America/Manaus<br />
America/Marigot<br />
America/Martinique<br />
America/Matamoros<br />
...<br />
</nowiki>}}<br />
# timedatectl set-timezone America/Los_Angeles<br />
<br />
=== Set hostname ===<br />
<br />
# hostnamectl set-hostname myhostname<br />
<br />
See the man page for {{Man|1|hostnamectl}} for other attributes that can be set. You might also add the hostname to {{Man|5|hosts}}:<br />
<br />
{{hc|/etc/hosts|<br />
127.0.0.1 localhost.localdomain localhost<br />
::1 localhost.localdomain localhost<br />
'''127.0.1.1 ''myhostname''.localdomain ''myhostname'''''<br />
}}<br />
<br />
Use {{ic|echo}} for a scriptable solution:<br />
<br />
# echo "127.0.1.1 myhostname.localdomain myhostname" >> /etc/hosts<br />
<br />
=== Network configuration ===<br />
<br />
Configure the network for the newly installed environment: see [[Network configuration]].<br />
<br />
For [[Wireless configuration]], [[Help:Reading#Installation of packages|install]] the {{Pkg|iw}}, {{Pkg|wpa_supplicant}}, and {{Pkg|dialog}} packages, as well as needed [[Wireless#Installing driver/firmware|firmware packages]].<br />
<br />
=== Base Package Installation ===<br />
<br />
We've already included the {{Grp|base}} group which is, strictly speaking, all you need to boot a minimal Arch Linux system. At this stage, however, we can install some useful utilities (and Xorg or Wayland, etc.).<br />
<br />
# pacman -Syu base-devel btrfs-progs iw gptfdisk zsh vim terminus-font<br />
<br />
=== Initramfs ===<br />
<br />
Creating a new ''initramfs'' is usually not required, because [[mkinitcpio]] was run on installation of the {{Pkg|linux}} package with ''pacstrap''. However we'll need to make some changes to the hooks used on our system. Additionally, I switched over to using the systemd hooks in mkinitcpio, so that is largely what you'll see in my example below.<br />
<br />
I recommend making a backup of your {{ic|/etc/mkinitcpio.conf}} file first:<br />
<br />
# mv /etc/mkinitcpio.conf /etc/mkinitcpio.conf.orig<br />
<br />
and then editing a new file to match the following contents:<br />
<br />
{{bc|<nowiki><br />
MODULES=""<br />
BINARIES=""<br />
FILES=""<br />
HOOKS="base systemd sd-vconsole modconf keyboard block filesystems btrfs sd-encrypt fsck"<br />
</nowiki>}}<br />
<br />
Finally, recreate the initramfs image:<br />
<br />
# mkinitcpio -p linux<br />
<br />
=== Bootloader ===<br />
<br />
{{Warning|THIS SECTION IN PROGRESS}}<br />
<br />
=== Root password ===<br />
<br />
Set the root [[password]]:<br />
<br />
# passwd<br />
<br />
=== Leave the systemd-nspawn environment ===<br />
<br />
Issue a poweroff to exit the nspawned environment:<br />
<br />
# poweroff<br />
<br />
This will return you the Arch installer environment where you can wrap up.<br />
<br />
=== Legacy boot loader ===<br />
<br />
If your system is not UEFI and you need to use a legacy installer like grub, it will need to be installed from within an arch-chroot generated chroot, not the systemd-nspawn running container. An example of this would be (assuming that the drive of the new system is at /dev/sdb):<br />
<br />
# arch-chroot /mnt<br />
# grub-install $DRIVE<br />
# grub-mkconfig -o /boot/grub/grub.cfg<br />
# exit<br />
<br />
== Command Summary ==<br />
<br />
The following are all critical commands (exluded: the initial drive wipe which is optional). It assumes you have successfully brought up networking prior to starting this sequence.<br />
<br />
{{bc|<nowiki><br />
<br />
$DRIVE=/dev/DRIVEID<br />
<br />
sgdisk --zap-all $DRIVE<br />
<br />
sgdisk --clear \<br />
--new=1:0:+550MiB --typecode=1:ef00 --change-name=1:EFI \<br />
--new=2:0:+8GiB --typecode=2:8200 --change-name=2:cryptswap \<br />
--new=3:0:0 --typecode=2:8200 --change-name=3:cryptsystem \<br />
$DRIVE<br />
<br />
mksf.fat -F32 -n EFI /dev/disk/by-partlabel/EFI<br />
<br />
cryptsetup luksFormat --align-payload=8192 -s 256 -c aes-xts-plain64 /dev/disk/by-partlabel/cryptsystem<br />
<br />
cryptsetup open /dev/disk/by-partlabel/cryptsystem system<br />
<br />
cryptsetup open --type plain --key-file /dev/urandom /dev/disk/by-partlabel/cryptswap swap<br />
<br />
mkswap -L swap /dev/mapper/swap<br />
<br />
swapon -L swap<br />
<br />
mkfs.btrfs --force --label system /dev/mapper/system<br />
<br />
o=defaults,x-mount.mkdir<br />
<br />
o_btrfs=$o,compress=lzo,ssd,noatime<br />
<br />
mount -t btrfs LABEL=system /mnt<br />
<br />
btrfs subvolume create /mnt/root<br />
<br />
btrfs subvolume create /mnt/home<br />
<br />
btrfs subvolume create /mnt/snapshots<br />
<br />
umount -R /mnt<br />
<br />
mount -t btrfs -o subvol=root,$o_btrfs LABEL=system /mnt<br />
<br />
mount -t btrfs -o subvol=home,$o_btrfs LABEL=system /mnt/home<br />
<br />
mount -t btrfs -o subvol=snapshots,$o_btrfs LABEL=system /mnt/.snapshots<br />
<br />
pacstrap /mnt base<br />
<br />
genfstab -L -p /mnt >> /mnt/etc/fstab<br />
<br />
sed -i "s+LABEL=swap+/dev/mapper/swap" /etc/fstab_labels<br />
<br />
systemd-nspawn -bD /mnt<br />
<br />
echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen<br />
<br />
locale-gen<br />
<br />
localectl set-locale LANG=en_US.UTF-8<br />
<br />
timedatectl set-ntp 1<br />
<br />
timedatectl set-timezone America/Los_Angeles<br />
<br />
hostnamectl set-hostname myhostname<br />
<br />
echo "127.0.1.1 myhostname.localdomain myhostname" >> /etc/hosts<br />
<br />
pacman -Syu base-devel btrfs-progs iw gptfdisk zsh vim terminus-font<br />
</nowiki>}}<br />
<br />
== Quick and Dirty ==<br />
<br />
{{Note|an extra example and may be moved to its own wiki page later}}<br />
<br />
This is the approximate process I follow if I want to bring up Arch on, say, an old laptop for a quick purpose built test machine, etc. It's not an install that I consider long term maintainable since rollbacks aren't implemented, nor is there any encryption, but it's a good example of how simple installation can be.<br />
<br />
{{bc|<nowiki><br />
$DRIVE=/dev/DRIVEID<br />
sgdisk --zap-all $DRIVE<br />
mkfs.btrfs -f $DRIVE<br />
mount -t btrfs $DRIVE /mnt<br />
pacstrap /mnt base<br />
systemd-nspawn -bD /mnt<br />
echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen<br />
locale-gen<br />
localectl set-locale LANG=en_US.UTF-8<br />
timedatectl set-ntp 1<br />
timedatectl set-timezone America/Los_Angeles<br />
hostnamectl set-hostname myhostname<br />
poweroff<br />
arch-chroot /mnt<br />
grub-install --root-directory=/mnt $DRIVE<br />
grub-mkconfig -o /mnt/boot/grub/grub.cfg<br />
exit<br />
reboot<br />
</nowiki>}}</div>Altercationhttps://wiki.archlinux.org/index.php?title=User:Altercation/Bullet_Proof_Arch_Install&diff=458570User:Altercation/Bullet Proof Arch Install2016-12-06T00:00:12Z<p>Altercation: /* Initramfs */</p>
<hr />
<div>This page is a summary of the current process I follow when installing Arch on a new laptop or desktop. My process varies over time, but this serves as my "state of the art" best practice recommendations. I'm open to feedback and suggestions for improvements.<br />
<br />
{{Note|This is entirely based on my own opinions and research. It is opinionated about the best way to do things given the current state of the kernel, hardware availability, and utilities, filesystems, etc. I will explain my rationale for specific choices and provide links to other sources of information (on the Arch wiki or external) where useful.}}<br />
<br />
== Objectives ==<br />
<br />
The goals of my standard "bullet proof" Arch Linux installation are:<br />
<br />
* Benefit from Arch's rolling release model while mitigating any risk of system corruption or data loss due to failed upgrades<br />
* Minimize risk due to hardware failure or total system loss (e.g. theft or physical destruction)<br />
* Make system rollbacks easy and procedural, using a standard setup and methodology for recovery of previous system (and user data) states<br />
<br />
=== Why not the Arch Install instructions? ===<br />
<br />
The [[Installation guide|Arch Linux installation instructions]] are an excellent, general starting point and you should read and understand them. That being said, they are designed to map to a very, very broad set of installation scenarios. I am interested in a very specific type of installation (daily use desktops and laptops in this article) and I have a strong set of opinions about the "right" or "best practice" way to set up my own working systems.<br />
<br />
These instructions, then, are much more prescriptive and have strong suggestions or directions about how (and why) one should use a particular method during Arch Linux installation.<br />
<br />
=== Key differences from the stock Arch install instructions ===<br />
<br />
How these instructions differ from the standard Arch guidance:<br />
<br />
* We are encrypting the entire system but not using LVM as is often recommended (see the encryption section below for details about why we are not using it).<br />
* I use labels and avoid UUIDs where possible to make switching to an alternate recovery drive easier.<br />
* I skip arch-chroot and simply boot the new system ('''not''' reboot, just boot) from within the install environment using {{Man|1|systemd-nspawn}} which enables the *ctl commands to work (and systemd services to be enabled properly without need for a system reboot)<br />
* I use the various systemd *ctl commands (hostnamectl, timedatectl, localectl, etc.) to configure the system<br />
* I use the systemd mkinitcpio hooks in lieu of the legacy hooks.<br />
* I use BTRFS exclusively for root and home partitions for its backup capabilities.<br />
* I recommend and use secure boot (but not with the Microsoft keys) to minimize risk due to the unavoidably unencrypted EFI partition.<br />
<br />
== Assumptions ==<br />
<br />
These instructions presuppose the following:<br />
<br />
* fairly new hardware (these instructions may work on older hardware, but there may be unusual issues that crop up... if you aren't comfortable handling those situations you should consider a more "traditional" Arch Linux install (e.g. using grub, LVM, ext4, etc.)<br />
* [[Unified Extensible Firmware Interface|UEFI support]] (BIOS system install is also possible with some modification of these instructions, but this has not yet been detailed here)<br />
* probably an [[Solid State Drives|SSD]].<br />
* some familiarity with Arch, or at least some experience with Linux, will help<br />
<br />
{{Warning|I am assuming you are going to single boot (not dual boot) and that you are '''willing to wipe all data from the install drive.''' If that is not the case, do not proceed with these instructions as following them '''will effectively destroy any data (and other operating systems) on the installation target drive.'''}}<br />
<br />
== Prerequisites ==<br />
<br />
You must have a recent copy of the Arch install USB. See [[:Category:Getting and installing Arch]] for general information and [[USB flash installation media]] for specific details on creating a USB Arch installation drive.<br />
<br />
You should also have a reasonable amount of time in which to complete the installation. Novice users will want to budget a couple hours. Experienced users will ''know'' to budget a couple hours.<br />
<br />
== Preparation ==<br />
<br />
=== Boot from USB Drive ===<br />
<br />
Boot your system from your prepared [[USB flash installation media|Arch Linux USB drive]]. It is important that you boot in EFI mode, not legacy BIOS compatibility mode. See the [[Unified Extensible Firmware Interface|UEFI]] article for more information about checking boot mode and ensuring you are booting using EFI.<br />
<br />
=== Bring up the network ===<br />
<br />
If you booted into a system with an ethernet cable plugged in, chances are you're up and running. If you need to use wireless instead, {{ic|wifi-menu}} will more often than not work without trouble. If those don't work, see [[Installation guide#Connect to the Internet|the Arch installation guide section on connecting to the internet]].<br />
<br />
=== Select Drive ===<br />
<br />
I like to use the [[Core utilities#lsblk|{{ic|1=lsblk}}]] command to bring up a quick list of the block devices on the system and identify existing partition structures and sizes, as well as mount points. If you don't already use it, I recommend [[Core utilities#lsblk|{{ic|1=lsblk}}]] when you need information on any given drive or partition. It's useful for polling UUIDs as well. For example, the following command gives you a clearly formatted summary of all block devices, their partition labels, filesystem lables, UUIDs and partition UUIDS: {{ic|lsblk -o +LABEL,PARTLABEL,UUID,PARTUUID}}<br />
<br />
In any case, the plain command without options should be enough to identify the drive you will install to (for example {{ic|1=/dev/sda}} or {{ic|1=/dev/nvme0n1}}:<br />
<br />
# lsblk<br />
<br />
=== Wipe Drive Securely (optional) ===<br />
<br />
While it is not necessary, given that this process will go through the trouble of encrypting the main system partition, it makes sense to do a secure wipe of the drive. This is more or less directly from [[Dm-crypt/Drive preparation#dm-crypt wipe on an empty disk or partition]].<br />
<br />
{{Warning|Be certain of your target device selection as we will be '''wiping this drive''' (either securely or, at minimum, destroying all existing partition data).}}<br />
<br />
First, create a temporary encrypted container the full disk ({{ic|sdX}}) to be encrypted, e.g. using default encryption parameters and a random key via the {{ic|--key-file /dev/{u}random}} option (see also [[Random number generation]]):<br />
<br />
# cryptsetup open --type plain /dev/sdXY container --key-file /dev/urandom<br />
<br />
{{Note|An interesting page addressing myths about /dev/urandom can be [http://www.2uo.de/myths-about-urandom/ found here]}}<br />
<br />
Second, check the container exists:<br />
<br />
{{hc|# fdisk -l|Disk /dev/mapper/container: XXXX MB, XXXXXXXXXX bytes<br />
...<br />
Disk /dev/mapper/container does not contain a valid partition table}}<br />
Wipe the container with zeros. A use of {{ic|1=if=/dev/urandom}} is '''not''' required as the encryption cipher itself generates randomness.<br />
{{hc|# dd <nowiki>if=/dev/zero of=/dev/mapper/container status=progress bs=1M</nowiki>|<br />
dd: writing to ‘/dev/mapper/container’: No space left on device}}<br />
<br />
{{Tip|<br />
* Using ''dd'' with the {{ic|1=bs=}} option, e.g. {{ic|1=bs=1M}} as above, is frequently used to increase disk throughput of the operation.<br />
* To perform a check of the operation, zero the partition before creating the wipe container. After the wipe command {{ic|blockdev --getsize64 ''/dev/mapper/container''}} can be used to get the exact container size as root. Now ''od'' can be used to spotcheck whether the wipe overwrote the zeroed sectors, e.g. {{ic|od -j ''containersize - blocksize''}} to view the wipe completed to the end.}}<br />
<br />
Finally, close the temporary container:<br />
<br />
# cryptsetup close container<br />
<br />
== Partition & Format Drive ==<br />
<br />
=== Understanding some basics about disks, partitions, and filesystems ===<br />
<br />
Think of your drive like a big empty building, no rooms. This is your plain physical drive (either a spinning platter drive or an SSD). Next imagine that to make it useful, we divide the building into apartments. In our analogy the apartments are '''partitions''' of the drive.<br />
<br />
Imagine also that there are a couple different standard methods of creating layout maps to the apartments. These plans are standardized so that the public services that have to access the building regularly (like the fire and police, for example) understand how to find the apartment entrances. In the world of partitioning, the equivalent is the "partition table scheme". The two common schemes are called "MBR" (Master Boot Record, older) and "GPT" (GUID Partition Table, newer). We will be using the new GPT scheme.<br />
<br />
Finally, imagine that the apartments are just empty shells. The act of building walls and laying out the functional structure of the apartments is equivalent to formatting our disk partitions with a filesystem. And just as different layouts may be more or less efficient, or have other different functional characteristics, so to filesystems have different attributes that make them useful in different ways.<br />
<br />
=== Our partition plans ===<br />
<br />
We will take our physical drive and divide it into three partitions. These partitions each serve a distinct purpose. All but the first and smallest, the EFI partition, will be encrypted. For security, if your system supports Secure Boot, you may choose to cryptographically sign the data stored on the EFI partition so that any tampering will be evident, despite the lack of encryption on that partition.<br />
<br />
{{Note|Again, we're assuming an UEFI installation (not legacy BIOS) and a GPT (not MBR) partition structure. If none of that made sense, best to start with the [[Partitioning]] article or do some test installs of Arch first. '''Partitioning is, in my opinion, one of the areas that is most confusing for the new Arch user.''' Additionally, there is a lot "received wisdom" and cargo-cult assumption making about how best to partition. Working through some of the "this is how it's always been done" tutorials isn't necessarily a bad thing... In many cases the way it has always been done has some sound reasoning behind it, despite being cargo-culted half the time. That being said, the method presented here is different from that in most of the Arch wiki partitioning methodologies.}}<br />
<br />
We will not be using LVM. You read a lot about LUKS and LVM and it all gets a bit complicated (LVM on LUKS, LUKS on LVM, etc.). LVM is a "logical volume manager" and abstracts physical devices (drives) into virtual devices, for easier management. It's a good idea but we will be using btrfs to effectively achieve the same results and really don't need the overhead of LVM.<br />
<br />
=== Partition Summary ===<br />
<br />
* 1: EFI - The UEFI 'bios" will look for this FAT32 formatted partition and either locate a default bootloader or will locate a specific EFI boot entry on it. This partition is by necessity not encrypted (unless the drive it is on has been encrypted as a "self encrypting drive")<br />
* 2: Swap - Used by Linux to swap out pages of memory from RAM to disk. Despite debate in this area, it is advisable to have at least some swap space, even it you are not planning on using hibernation on your machine. The Arch wiki is unfortunately rather too brief in its own [[Swap|swap article]] so I recommend the [https://docs.fedoraproject.org/en-US/Fedora/14/html/Storage_Administration_Guide/ch-swapspace.html Fedora documentation on swap] for a good overview on determining the right swap partition size.<br />
* 3: System - This will hold our root and home data. It will be formatted as BTRFS and will use subvolumes to manage snapshots of the current root and home contents.<br />
<br />
=== Visual overview of our partitions, filesystems, and contents ===<br />
<br />
This is a visual summary of our partions (inc. size information), encryption, filesystems, and a summary of the contents of each container.<br />
<br />
{| class="wikitable"<br />
| style="vertical-align: top; padding:1em" | '''Partition 1 (EFI)'''<br />
550MiB+<br />
{| style="border: 1px solid black; background: #DACEF2; margin: 1em;"<br />
! FAT32<br />
|-<br />
|kernel & initramfs<br />
(signed if using secure boot)<br />
|}<br />
| style="vertical-align: top; padding:1em" | '''Partition 2 (Swap)'''<br />
w/ Hibernate: Equal RAM,<br />
w/o Hibernate: min 8GB<br />
{| style="border: 1px solid black; background: #F2ECCE; margin: 1em;"<br />
|-<br />
! dm-crypt<br />
{| style="border: 1px solid black; background: #DACEF2; margin: 1em;"<br />
| SWAP<br />
|}<br />
|}<br />
| style="vertical-align: top; padding:1em" | '''Partition 3 (System)'''<br />
Remaining Space<br />
{| style="border: 1px solid black; background: #F2ECCE; margin: 1em;"<br />
|-<br />
! LUKS dm-crypt<br />
<br />
{| style="border: 1px solid black; background: #DACEF2; margin: 1em;"<br />
| BTRFS Top Level Subvolume<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Root Subvolume<br />
|}<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Home Subvolume<br />
|}<br />
<br />
{| style="border: 1px solid black; background: #E0CEF2; margin: 1em;"<br />
| BTRFS Snapshots Subvolume<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Root Snapshot Subvolume(s)<br />
|}<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Home Snapshot Subvolume(s)<br />
|}<br />
<br />
|}<br />
<br />
|}<br />
<br />
|}<br />
<br />
|}<br />
<br />
=== Partition Drive ===<br />
<br />
There are many utilities available for [[Partitioning]]. Because we are using Arch Linux and the command line doesn't hurt us (it makes us stronger) we will be using pure, non-interactive command line tools for this. Specifically, we will be using the utility [[Fdisk#Using_sgdisk|sgdisk]] from the {{Pkg|gptfdisk}} package. The [[Fdisk|fdisk]] utility now also supports GPT partitioned drives, so it would be an alternative. [[Fdisk#Using_sgdisk|sgdisk]] is available by default on the standard Arch install iso that you use to make your bootable USB drive.<br />
<br />
First, select the drive you will install to. Make sure you have selected the correct drive!. Again, a quick {{ic|lsblk}} will work here.<br />
<br />
# $DRIVE=/dev/DRIVEID<br />
<br />
(replace /dev/DRIVEID with the correct value, for example /dev/sda, /dev/nvme0n1, etc.)<br />
<br />
If you didn't securely wipe the drive already, it's worth "zapping" it using [[Fdisk#Using_sgdisk|sgdisk]] to remove any lingering legacy partition information. If you already wiped the drive you can skip this command (though it won't hurt to run it again).<br />
<br />
{{Warning|'''This command will also effectively erase the selected drive!'''}}<br />
<br />
# sgdisk --zap-all $DRIVE<br />
<br />
The following command will then create all three partitions in one go. '''It will also effectively erase the selected drive!'''<br />
<br />
# sgdisk --clear \<br />
--new=1:0:+550MiB --typecode=1:ef00 --change-name=1:EFI \<br />
--new=2:0:+8GiB --typecode=2:8200 --change-name=2:cryptswap \<br />
--new=3:0:0 --typecode=2:8200 --change-name=3:cryptsystem \<br />
$DRIVE<br />
<br />
It is worth noting that the "--change-name" values are, in this case, creating GPT "partition labels". You can subsequently see these by using the {{ic|lsblk -o +PARTLABEL}} command. It is good to use "EFI" for the efi partition. I am not aware of UEFI implementations that actively use the label for identification of the EFI partition, but it is possible that some do (UEFI bios implementations are not always consistent or to spec). The other two names are entirely "arbitrary". There is nothing special about calling them cryptswap and cryptsystem; they are simply good, clear names that remind us of the purpose of this partition and what it contains (for example, "cryptswap" suggests "this partition is for swap, and is encrypted").<br />
<br />
One final note about partition labels: we want them to be unique on your system. If for some reason there is already a GPT partition with the name EFI on another drive on your system, either change that partition name or use something besides "EFI" to avoid a namespace collision.<br />
<br />
Note also, that the backslashes at the end of each line can be omitted if you are writing the command on one long line instead. Those simply allow the splitting of a single command onto multiple lines.<br />
<br />
=== Format EFI Partition ===<br />
<br />
Next up: format the first (EFI) partition using the (required) FAT32 filesystem.<br />
<br />
# mksf.fat -F32 -n EFI /dev/disk/by-partlabel/EFI<br />
<br />
Note that we here make use of the partition label we just assigned. I prefer doing this since it simplifies scripts significantly for me and makes them, in my opinion, more readable.<br />
<br />
=== Encrypt System Partition ===<br />
<br />
Encrypt the main partition. Use a good passphrase. Note that the "--align-payload" value has been used as per [http://www.spinics.net/lists/dm-crypt/msg02421.html this suggestion/explanation] on the dm-crypt mailing list.<br />
<br />
Note also that I selected the encryption algorithm and key size using cryptsetup benchmark. See the [[Dm-crypt/Device_encryption]] article for more details.<br />
<br />
# cryptsetup luksFormat --align-payload=8192 -s 256 -c aes-xts-plain64 /dev/disk/by-partlabel/cryptsystem<br />
<br />
After creating the encrypted container, open it. Again, note the use of the partition label to identify the drive. Additionally, note that once we open this device we are giving it a name of "system." Thus "cryptsystem" is the encrypted system partition, while "system" is the name we are using once it has been opened in an unencrypted state. These names are arbitrary (Linux doesn't care what we use) but they help us keep things organized during this process.<br />
<br />
# cryptsetup open /dev/disk/by-partlabel/cryptsystem system<br />
<br />
=== Bring Up Encrypted Swap ===<br />
<br />
Finally we create encrypted swap. In this example we are not enabling hibernation. I will provide information on how to enable hibernation separately. Again, using partition labels to identify the partition and going from "cryptswap" to just "swap".<br />
<br />
We are not using LUKS here (which effectively makes dm-crypt easier to use). We're just using plain dm-crypt to encrypt the swap partition using a random key.<br />
<br />
# cryptsetup open --type plain --key-file /dev/urandom /dev/disk/by-partlabel/cryptswap swap<br />
# mkswap -L swap /dev/mapper/swap<br />
# swapon -L swap<br />
<br />
=== Create BTRFS Subvolumes ===<br />
<br />
Now on to the main attraction: creating our BTRFS subvolume structure. While BTRFS can be set up like any other filesystem (single command, just use the created file system directly), we're going to use the power of BTRFS to enable snapshotting our system state efficiently and rollbacks as necessary.<br />
<br />
First we create a top-level BTRFS subvolume. Note that the top-level entity in BTRFS nomenclature is still referred to as a '''sub'''volume, despite being at the top-level.<br />
<br />
We will create and mount this subvolume, create some new subvolumes inside it, and then switch to those subvolumes as our proper, mounted filesystems. Doing this will enable us to treat our root filesystem as a snapshotable object.<br />
<br />
Top-level subvolume creation.<br />
<br />
# mkfs.btrfs --force --label system /dev/mapper/system<br />
<br />
Temporarily mount our top-level volume for further subvolume creation. Note that the variable 'o' in this case is our default set of options for any given filesystem mount, while "o_btrfs" are those plus some options specific to btrfs. The default option "x-mount.mkdir" is a neat trick that allows us to skip the creation of directories for mountpoints (they will be created automatically). We assume /mnt as the standard mount point, as in a normal Arch Linux installation.<br />
<br />
# o=defaults,x-mount.mkdir<br />
# o_btrfs=$o,compress=lzo,ssd,noatime<br />
<br />
Note the use of our filesystem label to mount our subvolume. This is distinct from the partition labels used earlier. See the Arch wiki article on [[Persistent_block_device_naming]] for more information.<br />
<br />
# mount -t btrfs LABEL=system /mnt<br />
<br />
Now we create the subvolumes which will actually be mounted in our running system:<br />
<br />
# btrfs subvolume create /mnt/root<br />
# btrfs subvolume create /mnt/home<br />
# btrfs subvolume create /mnt/snapshots<br />
<br />
Then we unmount everything...<br />
<br />
# umount -R /mnt<br />
<br />
And remount just the subvolumes under our top-level subvolume (which remains unmounted unless we need to do "surgery" and rollback to a previous system system):<br />
<br />
# mount -t btrfs -o subvol=root,$o_btrfs LABEL=system /mnt<br />
<br />
Before mounting the home and snapshots subvolumes, let's walk through that command so we understand what it's doing:<br />
<br />
The 'mount -t btrfs' just specifies that our filesystem is of type BTRFS. This is often not necessary since mount will attempt to identify the filesystem type, but being explicit is often the best strategy with command line utilities, so we identify the type here.<br />
<br />
We use our previously defined mount options with the $o_btrfs variable and add the additional option "subvol=root" (separating it from our other defaults with a comma, of course). The next part of the command is "LABEL=system". Combined this reads as "mount the filesystem with the 'system' label, and use the 'root' subvolume within that".<br />
<br />
Finally, all this gets mounted at our install root, which in this case is "/mnt".<br />
<br />
Now let's pick back up and mount our home and snapshots subvolumes. Note that while the subvolume name is "snapshots", we will mount it at ".snapshots" (note dot prefix for the mount point). This will keep our root directory listing clean but will still make it available at a reasonable mount location.<br />
<br />
# mount -t btrfs -o subvol=home,$o_btrfs LABEL=system /mnt/home<br />
# mount -t btrfs -o subvol=snapshots,$o_btrfs LABEL=system /mnt/.snapshots<br />
<br />
It it worth noting that in each case we are telling mount to use the same filesystem, namely the one labeled "system". However in each case we are also telling it to look for a different subvolume in that filesystem (via the "subvol=" option).<br />
<br />
With this done, we can move on to installing the actual system.<br />
<br />
== Installation of Base Arch Linux System ==<br />
<br />
We are currently running off the Arch installer root filesystem. We will first use the 'pacstrap' utility to start our installation and then we will boot into our new minimal system using systemd-nspawn.<br />
<br />
=== Install base package group ===<br />
<br />
# pacstrap /mnt base<br />
<br />
=== fstab Generation and Modification ===<br />
<br />
{{Note|In a simpler, non encrypted configuration it is possible to skip making an fstab altogether due to a standard known as the [https://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/ Discoverable Partitions Spec]. However given the complexity of our encrypted, btrfs subvolume configuration, we require an fstab at this time. It is possible that in future we might feasibly do away with the fstab almost entirely in this setup (see the [https://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/#whataboutautomaticmountingofbtrfssubvolumestovarhomeandsoon 'What about automatic mounting of btrfs subvolumes'] section on that page).}}<br />
<br />
Create an [[fstab]] filesystem table file, using labels (-L) to identify the filesystems.<br />
<br />
# genfstab -L -p /mnt >> /mnt/etc/fstab<br />
<br />
I prefer to use labels as this makes the system more portable to a backup drive. You should end up with something that looks pretty close to this:<br />
<br />
{{hc|# cat /mnt/etc/fstab|<nowiki><br />
# /dev/mapper/system UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=system / btrfs rw,noatime,compress=lzo,ssd,space_cache,subvolid=257,subvol=/root,subvol=root 0 0<br />
<br />
# /dev/mapper/system UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=system /home btrfs rw,noatime,compress=lzo,ssd,space_cache,subvolid=258,subvol=/home,subvol=home 0 0<br />
<br />
# /dev/mapper/system UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=system /.snapshots btrfs rw,noatime,compress=lzo,ssd,space_cache,subvolid=259,subvol=/snapshots,subvol=snapshots 0 0<br />
<br />
# /dev/nvme0n1p1 UUID=xxxx-xxxx<br />
LABEL=EFI /boot/EFI vfat rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro 0 2<br />
<br />
# /dev/mapper/swap UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=swap none swap defaults 0 0<br />
</nowiki>}}<br />
<br />
There is one problem, however. Swap will not remount this way (the plain dm-crypt partition with a random key will not have a label when it is recreated on reboot). You will have to change that line from this:<br />
<br />
{{bc|<nowiki>LABEL=swap none swap defaults 0 0</nowiki>}}<br />
<br />
to this:<br />
<br />
{{bc|/dev/mapper/swap none swap defaults 0 0}}<br />
<br />
This will ensure that the mapped device is opened as swap successfully. The other lines may remain unchanged.<br />
<br />
==== Use {{ic|sed}} instead ====<br />
<br />
As a (scriptable) alternative to the manual editing of your {{ic|/etc/fstab}} you could use {{Man|1|sed}} to edit the file in place:<br />
<br />
# sed -i "s+LABEL=swap+/dev/mapper/swap" /etc/fstab_labels<br />
<br />
=== Boot into new system ===<br />
<br />
# systemd-nspawn -bD /mnt<br />
<br />
This will boot your new base Arch Linux system. After the standard boot messages scroll by you will be presented with a login (enter {{ic|root}} and hit enter to login).<br />
<br />
=== Generate and set locale ===<br />
<br />
Next, edit and uncomment your desired locale(s) from {{ic|/etc/locale.gen}}. We use {{ic|vi}} in the example below, but you could use a simpler editor such as {{ic|nano}} if you wish.<br />
<br />
{{hc|vi /etc/locale.gen|<nowiki><br />
...<br />
#en_PH.UTF-8 UTF-8<br />
#en_PH ISO-8859-1<br />
#en_SG.UTF-8 UTF-8<br />
#en_SG ISO-8859-1<br />
#en_US.UTF-8 UTF-8<br />
#en_US ISO-8859-1<br />
#en_ZA.UTF-8 UTF-8<br />
#en_ZA ISO-8859-1<br />
#en_ZM UTF-8<br />
...<br />
</nowiki>}}<br />
<br />
Changing it to (for en_US.UTF-8 as a locale in this example):<br />
<br />
{{bc|<nowiki><br />
...<br />
#en_PH.UTF-8 UTF-8<br />
#en_PH ISO-8859-1<br />
#en_SG.UTF-8 UTF-8<br />
#en_SG ISO-8859-1<br />
en_US.UTF-8 UTF-8<br />
#en_US ISO-8859-1<br />
#en_ZA.UTF-8 UTF-8<br />
#en_ZA ISO-8859-1<br />
#en_ZM UTF-8<br />
...<br />
</nowiki>}}<br />
<br />
Alternately one could simply append a known value to the {{ic|/etc/locale.gen}} file:<br />
<br />
# echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen<br />
<br />
After either method, one runs the {{ic|locale-gen}} command to generate the locale files:<br />
<br />
# locale-gen<br />
<br />
Finally we use {{Man|1|systemd-firstboot}} or {{Man|1|localectl}} to set the system locale. Each of these effectively does the same thing which is to simply write to {{ic|/etc/locale.conf}} (which can simply be edited directly as per standard Arch install instructions).<br />
<br />
==== With systemd-firstboot ====<br />
<br />
{{Man|1|systemd-firstboot}} will prompt us for selection from our generated locales. It will only work if there is no assigned system locale. If you wish to make changes afterward you can use {{Man|1|localectl}}<br />
<br />
# systemd-firstboot --prompt-locale<br />
<br />
==== With localectl ====<br />
<br />
This is an alternate to using {{ic|systemd-firstboot --prompt-locale}}. It may also be used subsequent to that command if further changes to the locale are desired.<br />
<br />
If you need a reminder of which locales have been installed (during this install or later during system changes), use {{ic|localectl list-locales}}:<br />
<br />
{{hc|<nowiki># localectl list-locales</nowiki>|en_US.UTF-8}}<br />
<br />
We then use {{ic|localectl set-locale}}:<br />
<br />
# localectl set-locale LANG=en_US.UTF-8<br />
<br />
=== Time and Date ===<br />
<br />
Unless you have a reason not to, we'll turn on NTP synchronization.<br />
<br />
# timedatectl set-ntp 1<br />
<br />
Then list timezones and pick one<br />
<br />
{{hc|<nowiki># timedatectl list-timezones</nowiki>|<nowiki><br />
...<br />
America/Kentucky/Louisville<br />
America/Kentucky/Monticello<br />
America/Kralendijk<br />
America/La_Paz<br />
America/Lima<br />
America/Los_Angeles<br />
America/Lower_Princes<br />
America/Maceio<br />
America/Managua<br />
America/Manaus<br />
America/Marigot<br />
America/Martinique<br />
America/Matamoros<br />
...<br />
</nowiki>}}<br />
# timedatectl set-timezone America/Los_Angeles<br />
<br />
=== Set hostname ===<br />
<br />
# hostnamectl set-hostname myhostname<br />
<br />
See the man page for {{Man|1|hostnamectl}} for other attributes that can be set. You might also add the hostname to {{Man|5|hosts}}:<br />
<br />
{{hc|/etc/hosts|<br />
127.0.0.1 localhost.localdomain localhost<br />
::1 localhost.localdomain localhost<br />
'''127.0.1.1 ''myhostname''.localdomain ''myhostname'''''<br />
}}<br />
<br />
Use {{ic|echo}} for a scriptable solution:<br />
<br />
# echo "127.0.1.1 myhostname.localdomain myhostname" >> /etc/hosts<br />
<br />
=== Network configuration ===<br />
<br />
Configure the network for the newly installed environment: see [[Network configuration]].<br />
<br />
For [[Wireless configuration]], [[Help:Reading#Installation of packages|install]] the {{Pkg|iw}}, {{Pkg|wpa_supplicant}}, and {{Pkg|dialog}} packages, as well as needed [[Wireless#Installing driver/firmware|firmware packages]].<br />
<br />
=== Base Package Installation ===<br />
<br />
We've already included the {{Grp|base}} group which is, strictly speaking, all you need to boot a minimal Arch Linux system. At this stage, however, we can install some useful utilities (and Xorg or Wayland, etc.).<br />
<br />
# pacman -Syu base-devel btrfs-progs iw gptfdisk zsh vim terminus-font<br />
<br />
=== Initramfs ===<br />
<br />
Creating a new ''initramfs'' is usually not required, because [[mkinitcpio]] was run on installation of the {{Pkg|linux}} package with ''pacstrap''. However we'll need to make some changes to the hooks used on our system. Additionally, I switched over to using the systemd hooks in mkinitcpio, so that is largely what you'll see in my example below.<br />
<br />
I recommend making a backup of your {{ic|/etc/mkinitcpio.conf}} file first:<br />
<br />
# mv /etc/mkinitcpio.conf /etc/mkinitcpio.conf.orig<br />
<br />
and then editing a new file to match the following contents:<br />
<br />
{{bc|<nowiki><br />
MODULES=""<br />
BINARIES=""<br />
FILES=""<br />
HOOKS="base systemd sd-vconsole modconf keyboard block filesystems btrfs sd-encrypt fsck"<br />
</nowiki>}}<br />
<br />
Finally, recreate the initramfs image:<br />
<br />
# mkinitcpio -p linux<br />
<br />
=== Bootloader ===<br />
<br />
{{Warning|THIS SECTION IN PROGRESS}}<br />
<br />
=== Root password ===<br />
<br />
Set the root [[password]]:<br />
<br />
# passwd<br />
<br />
=== Leave the systemd-nspawn environment ===<br />
<br />
Issue a poweroff to exit the nspawned environment:<br />
<br />
# poweroff<br />
<br />
This will return you the Arch installer environment where you can wrap up.<br />
<br />
=== Legacy boot loader ===<br />
<br />
If your system is not UEFI and you need to use a legacy installer like grub, it will need to be installed from within an arch-chroot generated chroot, not the systemd-nspawn running container. An example of this would be (assuming that the drive of the new system is at /dev/sdb):<br />
<br />
# arch-chroot /mnt<br />
# grub-install $DRIVE<br />
# grub-mkconfig -o /boot/grub/grub.cfg<br />
# exit<br />
<br />
== Command Summary ==<br />
<br />
The following are all critical commands (exluded: the initial drive wipe which is optional). It assumes you have successfully brought up networking prior to starting this sequence.<br />
<br />
{{bc|<nowiki><br />
<br />
$DRIVE=/dev/DRIVEID<br />
<br />
sgdisk --zap-all $DRIVE<br />
<br />
sgdisk --clear \<br />
--new=1:0:+550MiB --typecode=1:ef00 --change-name=1:EFI \<br />
--new=2:0:+8GiB --typecode=2:8200 --change-name=2:cryptswap \<br />
--new=3:0:0 --typecode=2:8200 --change-name=3:cryptsystem \<br />
$DRIVE<br />
<br />
mksf.fat -F32 -n EFI /dev/disk/by-partlabel/EFI<br />
<br />
cryptsetup luksFormat --align-payload=8192 -s 256 -c aes-xts-plain64 /dev/disk/by-partlabel/cryptsystem<br />
<br />
cryptsetup open /dev/disk/by-partlabel/cryptsystem system<br />
<br />
cryptsetup open --type plain --key-file /dev/urandom /dev/disk/by-partlabel/cryptswap swap<br />
<br />
mkswap -L swap /dev/mapper/swap<br />
<br />
swapon -L swap<br />
<br />
mkfs.btrfs --force --label system /dev/mapper/system<br />
<br />
o=defaults,x-mount.mkdir<br />
<br />
o_btrfs=$o,compress=lzo,ssd,noatime<br />
<br />
mount -t btrfs LABEL=system /mnt<br />
<br />
btrfs subvolume create /mnt/root<br />
<br />
btrfs subvolume create /mnt/home<br />
<br />
btrfs subvolume create /mnt/snapshots<br />
<br />
umount -R /mnt<br />
<br />
mount -t btrfs -o subvol=root,$o_btrfs LABEL=system /mnt<br />
<br />
mount -t btrfs -o subvol=home,$o_btrfs LABEL=system /mnt/home<br />
<br />
mount -t btrfs -o subvol=snapshots,$o_btrfs LABEL=system /mnt/.snapshots<br />
<br />
pacstrap /mnt base<br />
<br />
genfstab -L -p /mnt >> /mnt/etc/fstab<br />
<br />
sed -i "s+LABEL=swap+/dev/mapper/swap" /etc/fstab_labels<br />
<br />
systemd-nspawn -bD /mnt<br />
<br />
echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen<br />
<br />
locale-gen<br />
<br />
localectl set-locale LANG=en_US.UTF-8<br />
<br />
timedatectl set-ntp 1<br />
<br />
timedatectl set-timezone America/Los_Angeles<br />
<br />
hostnamectl set-hostname myhostname<br />
<br />
echo "127.0.1.1 myhostname.localdomain myhostname" >> /etc/hosts<br />
<br />
pacman -Syu base-devel btrfs-progs iw gptfdisk zsh vim terminus-font<br />
</nowiki>}}<br />
<br />
== Quick and Dirty ==<br />
<br />
{{Note|an extra example and may be moved to its own wiki page later}}<br />
<br />
This is the approximate process I follow if I want to bring up Arch on, say, an old laptop for a quick purpose built test machine, etc. It's not an install that I consider long term maintainable since rollbacks aren't implemented, nor is there any encryption, but it's a good example of how simple installation can be.<br />
<br />
{{bc|<nowiki><br />
$DRIVE=/dev/DRIVEID<br />
sgdisk --zap-all $DRIVE<br />
mkfs.btrfs -f $DRIVE<br />
mount -t btrfs $DRIVE /mnt<br />
pacstrap /mnt base<br />
systemd-nspawn -bD /mnt<br />
echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen<br />
locale-gen<br />
localectl set-locale LANG=en_US.UTF-8<br />
timedatectl set-ntp 1<br />
timedatectl set-timezone America/Los_Angeles<br />
hostnamectl set-hostname myhostname<br />
poweroff<br />
arch-chroot /mnt<br />
grub-install --root-directory=/mnt $DRIVE<br />
grub-mkconfig -o /mnt/boot/grub/grub.cfg<br />
exit<br />
reboot<br />
</nowiki>}}</div>Altercationhttps://wiki.archlinux.org/index.php?title=User:Altercation/Bullet_Proof_Arch_Install&diff=458568User:Altercation/Bullet Proof Arch Install2016-12-05T23:42:18Z<p>Altercation: /* Extra: Sample "quick and dirty" Arch install using systemd-nspawn */</p>
<hr />
<div>This page is a summary of the current process I follow when installing Arch on a new laptop or desktop. My process varies over time, but this serves as my "state of the art" best practice recommendations. I'm open to feedback and suggestions for improvements.<br />
<br />
{{Note|This is entirely based on my own opinions and research. It is opinionated about the best way to do things given the current state of the kernel, hardware availability, and utilities, filesystems, etc. I will explain my rationale for specific choices and provide links to other sources of information (on the Arch wiki or external) where useful.}}<br />
<br />
== Objectives ==<br />
<br />
The goals of my standard "bullet proof" Arch Linux installation are:<br />
<br />
* Benefit from Arch's rolling release model while mitigating any risk of system corruption or data loss due to failed upgrades<br />
* Minimize risk due to hardware failure or total system loss (e.g. theft or physical destruction)<br />
* Make system rollbacks easy and procedural, using a standard setup and methodology for recovery of previous system (and user data) states<br />
<br />
=== Why not the Arch Install instructions? ===<br />
<br />
The [[Installation guide|Arch Linux installation instructions]] are an excellent, general starting point and you should read and understand them. That being said, they are designed to map to a very, very broad set of installation scenarios. I am interested in a very specific type of installation (daily use desktops and laptops in this article) and I have a strong set of opinions about the "right" or "best practice" way to set up my own working systems.<br />
<br />
These instructions, then, are much more prescriptive and have strong suggestions or directions about how (and why) one should use a particular method during Arch Linux installation.<br />
<br />
=== Key differences from the stock Arch install instructions ===<br />
<br />
How these instructions differ from the standard Arch guidance:<br />
<br />
* We are encrypting the entire system but not using LVM as is often recommended (see the encryption section below for details about why we are not using it).<br />
* I use labels and avoid UUIDs where possible to make switching to an alternate recovery drive easier.<br />
* I skip arch-chroot and simply boot the new system ('''not''' reboot, just boot) from within the install environment using {{Man|1|systemd-nspawn}} which enables the *ctl commands to work (and systemd services to be enabled properly without need for a system reboot)<br />
* I use the various systemd *ctl commands (hostnamectl, timedatectl, localectl, etc.) to configure the system<br />
* I use the systemd mkinitcpio hooks in lieu of the legacy hooks.<br />
* I use BTRFS exclusively for root and home partitions for its backup capabilities.<br />
* I recommend and use secure boot (but not with the Microsoft keys) to minimize risk due to the unavoidably unencrypted EFI partition.<br />
<br />
== Assumptions ==<br />
<br />
These instructions presuppose the following:<br />
<br />
* fairly new hardware (these instructions may work on older hardware, but there may be unusual issues that crop up... if you aren't comfortable handling those situations you should consider a more "traditional" Arch Linux install (e.g. using grub, LVM, ext4, etc.)<br />
* [[Unified Extensible Firmware Interface|UEFI support]] (BIOS system install is also possible with some modification of these instructions, but this has not yet been detailed here)<br />
* probably an [[Solid State Drives|SSD]].<br />
* some familiarity with Arch, or at least some experience with Linux, will help<br />
<br />
{{Warning|I am assuming you are going to single boot (not dual boot) and that you are '''willing to wipe all data from the install drive.''' If that is not the case, do not proceed with these instructions as following them '''will effectively destroy any data (and other operating systems) on the installation target drive.'''}}<br />
<br />
== Prerequisites ==<br />
<br />
You must have a recent copy of the Arch install USB. See [[:Category:Getting and installing Arch]] for general information and [[USB flash installation media]] for specific details on creating a USB Arch installation drive.<br />
<br />
You should also have a reasonable amount of time in which to complete the installation. Novice users will want to budget a couple hours. Experienced users will ''know'' to budget a couple hours.<br />
<br />
== Preparation ==<br />
<br />
=== Boot from USB Drive ===<br />
<br />
Boot your system from your prepared [[USB flash installation media|Arch Linux USB drive]]. It is important that you boot in EFI mode, not legacy BIOS compatibility mode. See the [[Unified Extensible Firmware Interface|UEFI]] article for more information about checking boot mode and ensuring you are booting using EFI.<br />
<br />
=== Bring up the network ===<br />
<br />
If you booted into a system with an ethernet cable plugged in, chances are you're up and running. If you need to use wireless instead, {{ic|wifi-menu}} will more often than not work without trouble. If those don't work, see [[Installation guide#Connect to the Internet|the Arch installation guide section on connecting to the internet]].<br />
<br />
=== Select Drive ===<br />
<br />
I like to use the [[Core utilities#lsblk|{{ic|1=lsblk}}]] command to bring up a quick list of the block devices on the system and identify existing partition structures and sizes, as well as mount points. If you don't already use it, I recommend [[Core utilities#lsblk|{{ic|1=lsblk}}]] when you need information on any given drive or partition. It's useful for polling UUIDs as well. For example, the following command gives you a clearly formatted summary of all block devices, their partition labels, filesystem lables, UUIDs and partition UUIDS: {{ic|lsblk -o +LABEL,PARTLABEL,UUID,PARTUUID}}<br />
<br />
In any case, the plain command without options should be enough to identify the drive you will install to (for example {{ic|1=/dev/sda}} or {{ic|1=/dev/nvme0n1}}:<br />
<br />
# lsblk<br />
<br />
=== Wipe Drive Securely (optional) ===<br />
<br />
While it is not necessary, given that this process will go through the trouble of encrypting the main system partition, it makes sense to do a secure wipe of the drive. This is more or less directly from [[Dm-crypt/Drive preparation#dm-crypt wipe on an empty disk or partition]].<br />
<br />
{{Warning|Be certain of your target device selection as we will be '''wiping this drive''' (either securely or, at minimum, destroying all existing partition data).}}<br />
<br />
First, create a temporary encrypted container the full disk ({{ic|sdX}}) to be encrypted, e.g. using default encryption parameters and a random key via the {{ic|--key-file /dev/{u}random}} option (see also [[Random number generation]]):<br />
<br />
# cryptsetup open --type plain /dev/sdXY container --key-file /dev/urandom<br />
<br />
{{Note|An interesting page addressing myths about /dev/urandom can be [http://www.2uo.de/myths-about-urandom/ found here]}}<br />
<br />
Second, check the container exists:<br />
<br />
{{hc|# fdisk -l|Disk /dev/mapper/container: XXXX MB, XXXXXXXXXX bytes<br />
...<br />
Disk /dev/mapper/container does not contain a valid partition table}}<br />
Wipe the container with zeros. A use of {{ic|1=if=/dev/urandom}} is '''not''' required as the encryption cipher itself generates randomness.<br />
{{hc|# dd <nowiki>if=/dev/zero of=/dev/mapper/container status=progress bs=1M</nowiki>|<br />
dd: writing to ‘/dev/mapper/container’: No space left on device}}<br />
<br />
{{Tip|<br />
* Using ''dd'' with the {{ic|1=bs=}} option, e.g. {{ic|1=bs=1M}} as above, is frequently used to increase disk throughput of the operation.<br />
* To perform a check of the operation, zero the partition before creating the wipe container. After the wipe command {{ic|blockdev --getsize64 ''/dev/mapper/container''}} can be used to get the exact container size as root. Now ''od'' can be used to spotcheck whether the wipe overwrote the zeroed sectors, e.g. {{ic|od -j ''containersize - blocksize''}} to view the wipe completed to the end.}}<br />
<br />
Finally, close the temporary container:<br />
<br />
# cryptsetup close container<br />
<br />
== Partition & Format Drive ==<br />
<br />
=== Understanding some basics about disks, partitions, and filesystems ===<br />
<br />
Think of your drive like a big empty building, no rooms. This is your plain physical drive (either a spinning platter drive or an SSD). Next imagine that to make it useful, we divide the building into apartments. In our analogy the apartments are '''partitions''' of the drive.<br />
<br />
Imagine also that there are a couple different standard methods of creating layout maps to the apartments. These plans are standardized so that the public services that have to access the building regularly (like the fire and police, for example) understand how to find the apartment entrances. In the world of partitioning, the equivalent is the "partition table scheme". The two common schemes are called "MBR" (Master Boot Record, older) and "GPT" (GUID Partition Table, newer). We will be using the new GPT scheme.<br />
<br />
Finally, imagine that the apartments are just empty shells. The act of building walls and laying out the functional structure of the apartments is equivalent to formatting our disk partitions with a filesystem. And just as different layouts may be more or less efficient, or have other different functional characteristics, so to filesystems have different attributes that make them useful in different ways.<br />
<br />
=== Our partition plans ===<br />
<br />
We will take our physical drive and divide it into three partitions. These partitions each serve a distinct purpose. All but the first and smallest, the EFI partition, will be encrypted. For security, if your system supports Secure Boot, you may choose to cryptographically sign the data stored on the EFI partition so that any tampering will be evident, despite the lack of encryption on that partition.<br />
<br />
{{Note|Again, we're assuming an UEFI installation (not legacy BIOS) and a GPT (not MBR) partition structure. If none of that made sense, best to start with the [[Partitioning]] article or do some test installs of Arch first. '''Partitioning is, in my opinion, one of the areas that is most confusing for the new Arch user.''' Additionally, there is a lot "received wisdom" and cargo-cult assumption making about how best to partition. Working through some of the "this is how it's always been done" tutorials isn't necessarily a bad thing... In many cases the way it has always been done has some sound reasoning behind it, despite being cargo-culted half the time. That being said, the method presented here is different from that in most of the Arch wiki partitioning methodologies.}}<br />
<br />
We will not be using LVM. You read a lot about LUKS and LVM and it all gets a bit complicated (LVM on LUKS, LUKS on LVM, etc.). LVM is a "logical volume manager" and abstracts physical devices (drives) into virtual devices, for easier management. It's a good idea but we will be using btrfs to effectively achieve the same results and really don't need the overhead of LVM.<br />
<br />
=== Partition Summary ===<br />
<br />
* 1: EFI - The UEFI 'bios" will look for this FAT32 formatted partition and either locate a default bootloader or will locate a specific EFI boot entry on it. This partition is by necessity not encrypted (unless the drive it is on has been encrypted as a "self encrypting drive")<br />
* 2: Swap - Used by Linux to swap out pages of memory from RAM to disk. Despite debate in this area, it is advisable to have at least some swap space, even it you are not planning on using hibernation on your machine. The Arch wiki is unfortunately rather too brief in its own [[Swap|swap article]] so I recommend the [https://docs.fedoraproject.org/en-US/Fedora/14/html/Storage_Administration_Guide/ch-swapspace.html Fedora documentation on swap] for a good overview on determining the right swap partition size.<br />
* 3: System - This will hold our root and home data. It will be formatted as BTRFS and will use subvolumes to manage snapshots of the current root and home contents.<br />
<br />
=== Visual overview of our partitions, filesystems, and contents ===<br />
<br />
This is a visual summary of our partions (inc. size information), encryption, filesystems, and a summary of the contents of each container.<br />
<br />
{| class="wikitable"<br />
| style="vertical-align: top; padding:1em" | '''Partition 1 (EFI)'''<br />
550MiB+<br />
{| style="border: 1px solid black; background: #DACEF2; margin: 1em;"<br />
! FAT32<br />
|-<br />
|kernel & initramfs<br />
(signed if using secure boot)<br />
|}<br />
| style="vertical-align: top; padding:1em" | '''Partition 2 (Swap)'''<br />
w/ Hibernate: Equal RAM,<br />
w/o Hibernate: min 8GB<br />
{| style="border: 1px solid black; background: #F2ECCE; margin: 1em;"<br />
|-<br />
! dm-crypt<br />
{| style="border: 1px solid black; background: #DACEF2; margin: 1em;"<br />
| SWAP<br />
|}<br />
|}<br />
| style="vertical-align: top; padding:1em" | '''Partition 3 (System)'''<br />
Remaining Space<br />
{| style="border: 1px solid black; background: #F2ECCE; margin: 1em;"<br />
|-<br />
! LUKS dm-crypt<br />
<br />
{| style="border: 1px solid black; background: #DACEF2; margin: 1em;"<br />
| BTRFS Top Level Subvolume<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Root Subvolume<br />
|}<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Home Subvolume<br />
|}<br />
<br />
{| style="border: 1px solid black; background: #E0CEF2; margin: 1em;"<br />
| BTRFS Snapshots Subvolume<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Root Snapshot Subvolume(s)<br />
|}<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Home Snapshot Subvolume(s)<br />
|}<br />
<br />
|}<br />
<br />
|}<br />
<br />
|}<br />
<br />
|}<br />
<br />
=== Partition Drive ===<br />
<br />
There are many utilities available for [[Partitioning]]. Because we are using Arch Linux and the command line doesn't hurt us (it makes us stronger) we will be using pure, non-interactive command line tools for this. Specifically, we will be using the utility [[Fdisk#Using_sgdisk|sgdisk]] from the {{Pkg|gptfdisk}} package. The [[Fdisk|fdisk]] utility now also supports GPT partitioned drives, so it would be an alternative. [[Fdisk#Using_sgdisk|sgdisk]] is available by default on the standard Arch install iso that you use to make your bootable USB drive.<br />
<br />
First, select the drive you will install to. Make sure you have selected the correct drive!. Again, a quick {{ic|lsblk}} will work here.<br />
<br />
# $DRIVE=/dev/DRIVEID<br />
<br />
(replace /dev/DRIVEID with the correct value, for example /dev/sda, /dev/nvme0n1, etc.)<br />
<br />
If you didn't securely wipe the drive already, it's worth "zapping" it using [[Fdisk#Using_sgdisk|sgdisk]] to remove any lingering legacy partition information. If you already wiped the drive you can skip this command (though it won't hurt to run it again).<br />
<br />
{{Warning|'''This command will also effectively erase the selected drive!'''}}<br />
<br />
# sgdisk --zap-all $DRIVE<br />
<br />
The following command will then create all three partitions in one go. '''It will also effectively erase the selected drive!'''<br />
<br />
# sgdisk --clear \<br />
--new=1:0:+550MiB --typecode=1:ef00 --change-name=1:EFI \<br />
--new=2:0:+8GiB --typecode=2:8200 --change-name=2:cryptswap \<br />
--new=3:0:0 --typecode=2:8200 --change-name=3:cryptsystem \<br />
$DRIVE<br />
<br />
It is worth noting that the "--change-name" values are, in this case, creating GPT "partition labels". You can subsequently see these by using the {{ic|lsblk -o +PARTLABEL}} command. It is good to use "EFI" for the efi partition. I am not aware of UEFI implementations that actively use the label for identification of the EFI partition, but it is possible that some do (UEFI bios implementations are not always consistent or to spec). The other two names are entirely "arbitrary". There is nothing special about calling them cryptswap and cryptsystem; they are simply good, clear names that remind us of the purpose of this partition and what it contains (for example, "cryptswap" suggests "this partition is for swap, and is encrypted").<br />
<br />
One final note about partition labels: we want them to be unique on your system. If for some reason there is already a GPT partition with the name EFI on another drive on your system, either change that partition name or use something besides "EFI" to avoid a namespace collision.<br />
<br />
Note also, that the backslashes at the end of each line can be omitted if you are writing the command on one long line instead. Those simply allow the splitting of a single command onto multiple lines.<br />
<br />
=== Format EFI Partition ===<br />
<br />
Next up: format the first (EFI) partition using the (required) FAT32 filesystem.<br />
<br />
# mksf.fat -F32 -n EFI /dev/disk/by-partlabel/EFI<br />
<br />
Note that we here make use of the partition label we just assigned. I prefer doing this since it simplifies scripts significantly for me and makes them, in my opinion, more readable.<br />
<br />
=== Encrypt System Partition ===<br />
<br />
Encrypt the main partition. Use a good passphrase. Note that the "--align-payload" value has been used as per [http://www.spinics.net/lists/dm-crypt/msg02421.html this suggestion/explanation] on the dm-crypt mailing list.<br />
<br />
Note also that I selected the encryption algorithm and key size using cryptsetup benchmark. See the [[Dm-crypt/Device_encryption]] article for more details.<br />
<br />
# cryptsetup luksFormat --align-payload=8192 -s 256 -c aes-xts-plain64 /dev/disk/by-partlabel/cryptsystem<br />
<br />
After creating the encrypted container, open it. Again, note the use of the partition label to identify the drive. Additionally, note that once we open this device we are giving it a name of "system." Thus "cryptsystem" is the encrypted system partition, while "system" is the name we are using once it has been opened in an unencrypted state. These names are arbitrary (Linux doesn't care what we use) but they help us keep things organized during this process.<br />
<br />
# cryptsetup open /dev/disk/by-partlabel/cryptsystem system<br />
<br />
=== Bring Up Encrypted Swap ===<br />
<br />
Finally we create encrypted swap. In this example we are not enabling hibernation. I will provide information on how to enable hibernation separately. Again, using partition labels to identify the partition and going from "cryptswap" to just "swap".<br />
<br />
We are not using LUKS here (which effectively makes dm-crypt easier to use). We're just using plain dm-crypt to encrypt the swap partition using a random key.<br />
<br />
# cryptsetup open --type plain --key-file /dev/urandom /dev/disk/by-partlabel/cryptswap swap<br />
# mkswap -L swap /dev/mapper/swap<br />
# swapon -L swap<br />
<br />
=== Create BTRFS Subvolumes ===<br />
<br />
Now on to the main attraction: creating our BTRFS subvolume structure. While BTRFS can be set up like any other filesystem (single command, just use the created file system directly), we're going to use the power of BTRFS to enable snapshotting our system state efficiently and rollbacks as necessary.<br />
<br />
First we create a top-level BTRFS subvolume. Note that the top-level entity in BTRFS nomenclature is still referred to as a '''sub'''volume, despite being at the top-level.<br />
<br />
We will create and mount this subvolume, create some new subvolumes inside it, and then switch to those subvolumes as our proper, mounted filesystems. Doing this will enable us to treat our root filesystem as a snapshotable object.<br />
<br />
Top-level subvolume creation.<br />
<br />
# mkfs.btrfs --force --label system /dev/mapper/system<br />
<br />
Temporarily mount our top-level volume for further subvolume creation. Note that the variable 'o' in this case is our default set of options for any given filesystem mount, while "o_btrfs" are those plus some options specific to btrfs. The default option "x-mount.mkdir" is a neat trick that allows us to skip the creation of directories for mountpoints (they will be created automatically). We assume /mnt as the standard mount point, as in a normal Arch Linux installation.<br />
<br />
# o=defaults,x-mount.mkdir<br />
# o_btrfs=$o,compress=lzo,ssd,noatime<br />
<br />
Note the use of our filesystem label to mount our subvolume. This is distinct from the partition labels used earlier. See the Arch wiki article on [[Persistent_block_device_naming]] for more information.<br />
<br />
# mount -t btrfs LABEL=system /mnt<br />
<br />
Now we create the subvolumes which will actually be mounted in our running system:<br />
<br />
# btrfs subvolume create /mnt/root<br />
# btrfs subvolume create /mnt/home<br />
# btrfs subvolume create /mnt/snapshots<br />
<br />
Then we unmount everything...<br />
<br />
# umount -R /mnt<br />
<br />
And remount just the subvolumes under our top-level subvolume (which remains unmounted unless we need to do "surgery" and rollback to a previous system system):<br />
<br />
# mount -t btrfs -o subvol=root,$o_btrfs LABEL=system /mnt<br />
<br />
Before mounting the home and snapshots subvolumes, let's walk through that command so we understand what it's doing:<br />
<br />
The 'mount -t btrfs' just specifies that our filesystem is of type BTRFS. This is often not necessary since mount will attempt to identify the filesystem type, but being explicit is often the best strategy with command line utilities, so we identify the type here.<br />
<br />
We use our previously defined mount options with the $o_btrfs variable and add the additional option "subvol=root" (separating it from our other defaults with a comma, of course). The next part of the command is "LABEL=system". Combined this reads as "mount the filesystem with the 'system' label, and use the 'root' subvolume within that".<br />
<br />
Finally, all this gets mounted at our install root, which in this case is "/mnt".<br />
<br />
Now let's pick back up and mount our home and snapshots subvolumes. Note that while the subvolume name is "snapshots", we will mount it at ".snapshots" (note dot prefix for the mount point). This will keep our root directory listing clean but will still make it available at a reasonable mount location.<br />
<br />
# mount -t btrfs -o subvol=home,$o_btrfs LABEL=system /mnt/home<br />
# mount -t btrfs -o subvol=snapshots,$o_btrfs LABEL=system /mnt/.snapshots<br />
<br />
It it worth noting that in each case we are telling mount to use the same filesystem, namely the one labeled "system". However in each case we are also telling it to look for a different subvolume in that filesystem (via the "subvol=" option).<br />
<br />
With this done, we can move on to installing the actual system.<br />
<br />
== Installation of Base Arch Linux System ==<br />
<br />
We are currently running off the Arch installer root filesystem. We will first use the 'pacstrap' utility to start our installation and then we will boot into our new minimal system using systemd-nspawn.<br />
<br />
=== Install base package group ===<br />
<br />
# pacstrap /mnt base<br />
<br />
=== fstab Generation and Modification ===<br />
<br />
{{Note|In a simpler, non encrypted configuration it is possible to skip making an fstab altogether due to a standard known as the [https://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/ Discoverable Partitions Spec]. However given the complexity of our encrypted, btrfs subvolume configuration, we require an fstab at this time. It is possible that in future we might feasibly do away with the fstab almost entirely in this setup (see the [https://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/#whataboutautomaticmountingofbtrfssubvolumestovarhomeandsoon 'What about automatic mounting of btrfs subvolumes'] section on that page).}}<br />
<br />
Create an [[fstab]] filesystem table file, using labels (-L) to identify the filesystems.<br />
<br />
# genfstab -L -p /mnt >> /mnt/etc/fstab<br />
<br />
I prefer to use labels as this makes the system more portable to a backup drive. You should end up with something that looks pretty close to this:<br />
<br />
{{hc|# cat /mnt/etc/fstab|<nowiki><br />
# /dev/mapper/system UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=system / btrfs rw,noatime,compress=lzo,ssd,space_cache,subvolid=257,subvol=/root,subvol=root 0 0<br />
<br />
# /dev/mapper/system UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=system /home btrfs rw,noatime,compress=lzo,ssd,space_cache,subvolid=258,subvol=/home,subvol=home 0 0<br />
<br />
# /dev/mapper/system UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=system /.snapshots btrfs rw,noatime,compress=lzo,ssd,space_cache,subvolid=259,subvol=/snapshots,subvol=snapshots 0 0<br />
<br />
# /dev/nvme0n1p1 UUID=xxxx-xxxx<br />
LABEL=EFI /boot/EFI vfat rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro 0 2<br />
<br />
# /dev/mapper/swap UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=swap none swap defaults 0 0<br />
</nowiki>}}<br />
<br />
There is one problem, however. Swap will not remount this way (the plain dm-crypt partition with a random key will not have a label when it is recreated on reboot). You will have to change that line from this:<br />
<br />
{{bc|<nowiki>LABEL=swap none swap defaults 0 0</nowiki>}}<br />
<br />
to this:<br />
<br />
{{bc|/dev/mapper/swap none swap defaults 0 0}}<br />
<br />
This will ensure that the mapped device is opened as swap successfully. The other lines may remain unchanged.<br />
<br />
==== Use {{ic|sed}} instead ====<br />
<br />
As a (scriptable) alternative to the manual editing of your {{ic|/etc/fstab}} you could use {{Man|1|sed}} to edit the file in place:<br />
<br />
# sed -i "s+LABEL=swap+/dev/mapper/swap" /etc/fstab_labels<br />
<br />
=== Boot into new system ===<br />
<br />
# systemd-nspawn -bD /mnt<br />
<br />
This will boot your new base Arch Linux system. After the standard boot messages scroll by you will be presented with a login (enter {{ic|root}} and hit enter to login).<br />
<br />
=== Generate and set locale ===<br />
<br />
Next, edit and uncomment your desired locale(s) from {{ic|/etc/locale.gen}}. We use {{ic|vi}} in the example below, but you could use a simpler editor such as {{ic|nano}} if you wish.<br />
<br />
{{hc|vi /etc/locale.gen|<nowiki><br />
...<br />
#en_PH.UTF-8 UTF-8<br />
#en_PH ISO-8859-1<br />
#en_SG.UTF-8 UTF-8<br />
#en_SG ISO-8859-1<br />
#en_US.UTF-8 UTF-8<br />
#en_US ISO-8859-1<br />
#en_ZA.UTF-8 UTF-8<br />
#en_ZA ISO-8859-1<br />
#en_ZM UTF-8<br />
...<br />
</nowiki>}}<br />
<br />
Changing it to (for en_US.UTF-8 as a locale in this example):<br />
<br />
{{bc|<nowiki><br />
...<br />
#en_PH.UTF-8 UTF-8<br />
#en_PH ISO-8859-1<br />
#en_SG.UTF-8 UTF-8<br />
#en_SG ISO-8859-1<br />
en_US.UTF-8 UTF-8<br />
#en_US ISO-8859-1<br />
#en_ZA.UTF-8 UTF-8<br />
#en_ZA ISO-8859-1<br />
#en_ZM UTF-8<br />
...<br />
</nowiki>}}<br />
<br />
Alternately one could simply append a known value to the {{ic|/etc/locale.gen}} file:<br />
<br />
# echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen<br />
<br />
After either method, one runs the {{ic|locale-gen}} command to generate the locale files:<br />
<br />
# locale-gen<br />
<br />
Finally we use {{Man|1|systemd-firstboot}} or {{Man|1|localectl}} to set the system locale. Each of these effectively does the same thing which is to simply write to {{ic|/etc/locale.conf}} (which can simply be edited directly as per standard Arch install instructions).<br />
<br />
==== With systemd-firstboot ====<br />
<br />
{{Man|1|systemd-firstboot}} will prompt us for selection from our generated locales. It will only work if there is no assigned system locale. If you wish to make changes afterward you can use {{Man|1|localectl}}<br />
<br />
# systemd-firstboot --prompt-locale<br />
<br />
==== With localectl ====<br />
<br />
This is an alternate to using {{ic|systemd-firstboot --prompt-locale}}. It may also be used subsequent to that command if further changes to the locale are desired.<br />
<br />
If you need a reminder of which locales have been installed (during this install or later during system changes), use {{ic|localectl list-locales}}:<br />
<br />
{{hc|<nowiki># localectl list-locales</nowiki>|en_US.UTF-8}}<br />
<br />
We then use {{ic|localectl set-locale}}:<br />
<br />
# localectl set-locale LANG=en_US.UTF-8<br />
<br />
=== Time and Date ===<br />
<br />
Unless you have a reason not to, we'll turn on NTP synchronization.<br />
<br />
# timedatectl set-ntp 1<br />
<br />
Then list timezones and pick one<br />
<br />
{{hc|<nowiki># timedatectl list-timezones</nowiki>|<nowiki><br />
...<br />
America/Kentucky/Louisville<br />
America/Kentucky/Monticello<br />
America/Kralendijk<br />
America/La_Paz<br />
America/Lima<br />
America/Los_Angeles<br />
America/Lower_Princes<br />
America/Maceio<br />
America/Managua<br />
America/Manaus<br />
America/Marigot<br />
America/Martinique<br />
America/Matamoros<br />
...<br />
</nowiki>}}<br />
# timedatectl set-timezone America/Los_Angeles<br />
<br />
=== Set hostname ===<br />
<br />
# hostnamectl set-hostname myhostname<br />
<br />
See the man page for {{Man|1|hostnamectl}} for other attributes that can be set. You might also add the hostname to {{Man|5|hosts}}:<br />
<br />
{{hc|/etc/hosts|<br />
127.0.0.1 localhost.localdomain localhost<br />
::1 localhost.localdomain localhost<br />
'''127.0.1.1 ''myhostname''.localdomain ''myhostname'''''<br />
}}<br />
<br />
Use {{ic|echo}} for a scriptable solution:<br />
<br />
# echo "127.0.1.1 myhostname.localdomain myhostname" >> /etc/hosts<br />
<br />
=== Network configuration ===<br />
<br />
Configure the network for the newly installed environment: see [[Network configuration]].<br />
<br />
For [[Wireless configuration]], [[Help:Reading#Installation of packages|install]] the {{Pkg|iw}}, {{Pkg|wpa_supplicant}}, and {{Pkg|dialog}} packages, as well as needed [[Wireless#Installing driver/firmware|firmware packages]].<br />
<br />
=== Base Package Installation ===<br />
<br />
We've already included the {{Grp|base}} group which is, strictly speaking, all you need to boot a minimal Arch Linux system. At this stage, however, we can install some useful utilities (and Xorg or Wayland, etc.).<br />
<br />
# pacman -Syu base-devel btrfs-progs iw gptfdisk zsh vim terminus-font<br />
<br />
=== Initramfs ===<br />
<br />
Creating a new ''initramfs'' is usually not required, because [[mkinitcpio]] was run on installation of the {{Pkg|linux}} package with ''pacstrap''.<br />
<br />
For special configurations, modify the {{man|5|mkinitcpio.conf|url=}} file and recreate the initramfs image:<br />
<br />
# mkinitcpio -p linux<br />
<br />
=== Bootloader ===<br />
<br />
{{Warning|THIS SECTION IN PROGRESS}}<br />
<br />
=== Root password ===<br />
<br />
Set the root [[password]]:<br />
<br />
# passwd<br />
<br />
=== Leave the systemd-nspawn environment ===<br />
<br />
Issue a poweroff to exit the nspawned environment:<br />
<br />
# poweroff<br />
<br />
This will return you the Arch installer environment where you can wrap up.<br />
<br />
=== Legacy boot loader ===<br />
<br />
If your system is not UEFI and you need to use a legacy installer like grub, it will need to be installed from within an arch-chroot generated chroot, not the systemd-nspawn running container. An example of this would be (assuming that the drive of the new system is at /dev/sdb):<br />
<br />
# arch-chroot /mnt<br />
# grub-install $DRIVE<br />
# grub-mkconfig -o /boot/grub/grub.cfg<br />
# exit<br />
<br />
== Command Summary ==<br />
<br />
The following are all critical commands (exluded: the initial drive wipe which is optional). It assumes you have successfully brought up networking prior to starting this sequence.<br />
<br />
{{bc|<nowiki><br />
<br />
$DRIVE=/dev/DRIVEID<br />
<br />
sgdisk --zap-all $DRIVE<br />
<br />
sgdisk --clear \<br />
--new=1:0:+550MiB --typecode=1:ef00 --change-name=1:EFI \<br />
--new=2:0:+8GiB --typecode=2:8200 --change-name=2:cryptswap \<br />
--new=3:0:0 --typecode=2:8200 --change-name=3:cryptsystem \<br />
$DRIVE<br />
<br />
mksf.fat -F32 -n EFI /dev/disk/by-partlabel/EFI<br />
<br />
cryptsetup luksFormat --align-payload=8192 -s 256 -c aes-xts-plain64 /dev/disk/by-partlabel/cryptsystem<br />
<br />
cryptsetup open /dev/disk/by-partlabel/cryptsystem system<br />
<br />
cryptsetup open --type plain --key-file /dev/urandom /dev/disk/by-partlabel/cryptswap swap<br />
<br />
mkswap -L swap /dev/mapper/swap<br />
<br />
swapon -L swap<br />
<br />
mkfs.btrfs --force --label system /dev/mapper/system<br />
<br />
o=defaults,x-mount.mkdir<br />
<br />
o_btrfs=$o,compress=lzo,ssd,noatime<br />
<br />
mount -t btrfs LABEL=system /mnt<br />
<br />
btrfs subvolume create /mnt/root<br />
<br />
btrfs subvolume create /mnt/home<br />
<br />
btrfs subvolume create /mnt/snapshots<br />
<br />
umount -R /mnt<br />
<br />
mount -t btrfs -o subvol=root,$o_btrfs LABEL=system /mnt<br />
<br />
mount -t btrfs -o subvol=home,$o_btrfs LABEL=system /mnt/home<br />
<br />
mount -t btrfs -o subvol=snapshots,$o_btrfs LABEL=system /mnt/.snapshots<br />
<br />
pacstrap /mnt base<br />
<br />
genfstab -L -p /mnt >> /mnt/etc/fstab<br />
<br />
sed -i "s+LABEL=swap+/dev/mapper/swap" /etc/fstab_labels<br />
<br />
systemd-nspawn -bD /mnt<br />
<br />
echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen<br />
<br />
locale-gen<br />
<br />
localectl set-locale LANG=en_US.UTF-8<br />
<br />
timedatectl set-ntp 1<br />
<br />
timedatectl set-timezone America/Los_Angeles<br />
<br />
hostnamectl set-hostname myhostname<br />
<br />
echo "127.0.1.1 myhostname.localdomain myhostname" >> /etc/hosts<br />
<br />
pacman -Syu base-devel btrfs-progs iw gptfdisk zsh vim terminus-font<br />
</nowiki>}}<br />
<br />
== Quick and Dirty ==<br />
<br />
{{Note|an extra example and may be moved to its own wiki page later}}<br />
<br />
This is the approximate process I follow if I want to bring up Arch on, say, an old laptop for a quick purpose built test machine, etc. It's not an install that I consider long term maintainable since rollbacks aren't implemented, nor is there any encryption, but it's a good example of how simple installation can be.<br />
<br />
{{bc|<nowiki><br />
$DRIVE=/dev/DRIVEID<br />
sgdisk --zap-all $DRIVE<br />
mkfs.btrfs -f $DRIVE<br />
mount -t btrfs $DRIVE /mnt<br />
pacstrap /mnt base<br />
systemd-nspawn -bD /mnt<br />
echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen<br />
locale-gen<br />
localectl set-locale LANG=en_US.UTF-8<br />
timedatectl set-ntp 1<br />
timedatectl set-timezone America/Los_Angeles<br />
hostnamectl set-hostname myhostname<br />
poweroff<br />
arch-chroot /mnt<br />
grub-install --root-directory=/mnt $DRIVE<br />
grub-mkconfig -o /mnt/boot/grub/grub.cfg<br />
exit<br />
reboot<br />
</nowiki>}}</div>Altercationhttps://wiki.archlinux.org/index.php?title=User:Altercation/Bullet_Proof_Arch_Install&diff=458567User:Altercation/Bullet Proof Arch Install2016-12-05T23:16:29Z<p>Altercation: /* Legacy boot loader */</p>
<hr />
<div>This page is a summary of the current process I follow when installing Arch on a new laptop or desktop. My process varies over time, but this serves as my "state of the art" best practice recommendations. I'm open to feedback and suggestions for improvements.<br />
<br />
{{Note|This is entirely based on my own opinions and research. It is opinionated about the best way to do things given the current state of the kernel, hardware availability, and utilities, filesystems, etc. I will explain my rationale for specific choices and provide links to other sources of information (on the Arch wiki or external) where useful.}}<br />
<br />
== Objectives ==<br />
<br />
The goals of my standard "bullet proof" Arch Linux installation are:<br />
<br />
* Benefit from Arch's rolling release model while mitigating any risk of system corruption or data loss due to failed upgrades<br />
* Minimize risk due to hardware failure or total system loss (e.g. theft or physical destruction)<br />
* Make system rollbacks easy and procedural, using a standard setup and methodology for recovery of previous system (and user data) states<br />
<br />
=== Why not the Arch Install instructions? ===<br />
<br />
The [[Installation guide|Arch Linux installation instructions]] are an excellent, general starting point and you should read and understand them. That being said, they are designed to map to a very, very broad set of installation scenarios. I am interested in a very specific type of installation (daily use desktops and laptops in this article) and I have a strong set of opinions about the "right" or "best practice" way to set up my own working systems.<br />
<br />
These instructions, then, are much more prescriptive and have strong suggestions or directions about how (and why) one should use a particular method during Arch Linux installation.<br />
<br />
=== Key differences from the stock Arch install instructions ===<br />
<br />
How these instructions differ from the standard Arch guidance:<br />
<br />
* We are encrypting the entire system but not using LVM as is often recommended (see the encryption section below for details about why we are not using it).<br />
* I use labels and avoid UUIDs where possible to make switching to an alternate recovery drive easier.<br />
* I skip arch-chroot and simply boot the new system ('''not''' reboot, just boot) from within the install environment using {{Man|1|systemd-nspawn}} which enables the *ctl commands to work (and systemd services to be enabled properly without need for a system reboot)<br />
* I use the various systemd *ctl commands (hostnamectl, timedatectl, localectl, etc.) to configure the system<br />
* I use the systemd mkinitcpio hooks in lieu of the legacy hooks.<br />
* I use BTRFS exclusively for root and home partitions for its backup capabilities.<br />
* I recommend and use secure boot (but not with the Microsoft keys) to minimize risk due to the unavoidably unencrypted EFI partition.<br />
<br />
== Assumptions ==<br />
<br />
These instructions presuppose the following:<br />
<br />
* fairly new hardware (these instructions may work on older hardware, but there may be unusual issues that crop up... if you aren't comfortable handling those situations you should consider a more "traditional" Arch Linux install (e.g. using grub, LVM, ext4, etc.)<br />
* [[Unified Extensible Firmware Interface|UEFI support]] (BIOS system install is also possible with some modification of these instructions, but this has not yet been detailed here)<br />
* probably an [[Solid State Drives|SSD]].<br />
* some familiarity with Arch, or at least some experience with Linux, will help<br />
<br />
{{Warning|I am assuming you are going to single boot (not dual boot) and that you are '''willing to wipe all data from the install drive.''' If that is not the case, do not proceed with these instructions as following them '''will effectively destroy any data (and other operating systems) on the installation target drive.'''}}<br />
<br />
== Prerequisites ==<br />
<br />
You must have a recent copy of the Arch install USB. See [[:Category:Getting and installing Arch]] for general information and [[USB flash installation media]] for specific details on creating a USB Arch installation drive.<br />
<br />
You should also have a reasonable amount of time in which to complete the installation. Novice users will want to budget a couple hours. Experienced users will ''know'' to budget a couple hours.<br />
<br />
== Preparation ==<br />
<br />
=== Boot from USB Drive ===<br />
<br />
Boot your system from your prepared [[USB flash installation media|Arch Linux USB drive]]. It is important that you boot in EFI mode, not legacy BIOS compatibility mode. See the [[Unified Extensible Firmware Interface|UEFI]] article for more information about checking boot mode and ensuring you are booting using EFI.<br />
<br />
=== Bring up the network ===<br />
<br />
If you booted into a system with an ethernet cable plugged in, chances are you're up and running. If you need to use wireless instead, {{ic|wifi-menu}} will more often than not work without trouble. If those don't work, see [[Installation guide#Connect to the Internet|the Arch installation guide section on connecting to the internet]].<br />
<br />
=== Select Drive ===<br />
<br />
I like to use the [[Core utilities#lsblk|{{ic|1=lsblk}}]] command to bring up a quick list of the block devices on the system and identify existing partition structures and sizes, as well as mount points. If you don't already use it, I recommend [[Core utilities#lsblk|{{ic|1=lsblk}}]] when you need information on any given drive or partition. It's useful for polling UUIDs as well. For example, the following command gives you a clearly formatted summary of all block devices, their partition labels, filesystem lables, UUIDs and partition UUIDS: {{ic|lsblk -o +LABEL,PARTLABEL,UUID,PARTUUID}}<br />
<br />
In any case, the plain command without options should be enough to identify the drive you will install to (for example {{ic|1=/dev/sda}} or {{ic|1=/dev/nvme0n1}}:<br />
<br />
# lsblk<br />
<br />
=== Wipe Drive Securely (optional) ===<br />
<br />
While it is not necessary, given that this process will go through the trouble of encrypting the main system partition, it makes sense to do a secure wipe of the drive. This is more or less directly from [[Dm-crypt/Drive preparation#dm-crypt wipe on an empty disk or partition]].<br />
<br />
{{Warning|Be certain of your target device selection as we will be '''wiping this drive''' (either securely or, at minimum, destroying all existing partition data).}}<br />
<br />
First, create a temporary encrypted container the full disk ({{ic|sdX}}) to be encrypted, e.g. using default encryption parameters and a random key via the {{ic|--key-file /dev/{u}random}} option (see also [[Random number generation]]):<br />
<br />
# cryptsetup open --type plain /dev/sdXY container --key-file /dev/urandom<br />
<br />
{{Note|An interesting page addressing myths about /dev/urandom can be [http://www.2uo.de/myths-about-urandom/ found here]}}<br />
<br />
Second, check the container exists:<br />
<br />
{{hc|# fdisk -l|Disk /dev/mapper/container: XXXX MB, XXXXXXXXXX bytes<br />
...<br />
Disk /dev/mapper/container does not contain a valid partition table}}<br />
Wipe the container with zeros. A use of {{ic|1=if=/dev/urandom}} is '''not''' required as the encryption cipher itself generates randomness.<br />
{{hc|# dd <nowiki>if=/dev/zero of=/dev/mapper/container status=progress bs=1M</nowiki>|<br />
dd: writing to ‘/dev/mapper/container’: No space left on device}}<br />
<br />
{{Tip|<br />
* Using ''dd'' with the {{ic|1=bs=}} option, e.g. {{ic|1=bs=1M}} as above, is frequently used to increase disk throughput of the operation.<br />
* To perform a check of the operation, zero the partition before creating the wipe container. After the wipe command {{ic|blockdev --getsize64 ''/dev/mapper/container''}} can be used to get the exact container size as root. Now ''od'' can be used to spotcheck whether the wipe overwrote the zeroed sectors, e.g. {{ic|od -j ''containersize - blocksize''}} to view the wipe completed to the end.}}<br />
<br />
Finally, close the temporary container:<br />
<br />
# cryptsetup close container<br />
<br />
== Partition & Format Drive ==<br />
<br />
=== Understanding some basics about disks, partitions, and filesystems ===<br />
<br />
Think of your drive like a big empty building, no rooms. This is your plain physical drive (either a spinning platter drive or an SSD). Next imagine that to make it useful, we divide the building into apartments. In our analogy the apartments are '''partitions''' of the drive.<br />
<br />
Imagine also that there are a couple different standard methods of creating layout maps to the apartments. These plans are standardized so that the public services that have to access the building regularly (like the fire and police, for example) understand how to find the apartment entrances. In the world of partitioning, the equivalent is the "partition table scheme". The two common schemes are called "MBR" (Master Boot Record, older) and "GPT" (GUID Partition Table, newer). We will be using the new GPT scheme.<br />
<br />
Finally, imagine that the apartments are just empty shells. The act of building walls and laying out the functional structure of the apartments is equivalent to formatting our disk partitions with a filesystem. And just as different layouts may be more or less efficient, or have other different functional characteristics, so to filesystems have different attributes that make them useful in different ways.<br />
<br />
=== Our partition plans ===<br />
<br />
We will take our physical drive and divide it into three partitions. These partitions each serve a distinct purpose. All but the first and smallest, the EFI partition, will be encrypted. For security, if your system supports Secure Boot, you may choose to cryptographically sign the data stored on the EFI partition so that any tampering will be evident, despite the lack of encryption on that partition.<br />
<br />
{{Note|Again, we're assuming an UEFI installation (not legacy BIOS) and a GPT (not MBR) partition structure. If none of that made sense, best to start with the [[Partitioning]] article or do some test installs of Arch first. '''Partitioning is, in my opinion, one of the areas that is most confusing for the new Arch user.''' Additionally, there is a lot "received wisdom" and cargo-cult assumption making about how best to partition. Working through some of the "this is how it's always been done" tutorials isn't necessarily a bad thing... In many cases the way it has always been done has some sound reasoning behind it, despite being cargo-culted half the time. That being said, the method presented here is different from that in most of the Arch wiki partitioning methodologies.}}<br />
<br />
We will not be using LVM. You read a lot about LUKS and LVM and it all gets a bit complicated (LVM on LUKS, LUKS on LVM, etc.). LVM is a "logical volume manager" and abstracts physical devices (drives) into virtual devices, for easier management. It's a good idea but we will be using btrfs to effectively achieve the same results and really don't need the overhead of LVM.<br />
<br />
=== Partition Summary ===<br />
<br />
* 1: EFI - The UEFI 'bios" will look for this FAT32 formatted partition and either locate a default bootloader or will locate a specific EFI boot entry on it. This partition is by necessity not encrypted (unless the drive it is on has been encrypted as a "self encrypting drive")<br />
* 2: Swap - Used by Linux to swap out pages of memory from RAM to disk. Despite debate in this area, it is advisable to have at least some swap space, even it you are not planning on using hibernation on your machine. The Arch wiki is unfortunately rather too brief in its own [[Swap|swap article]] so I recommend the [https://docs.fedoraproject.org/en-US/Fedora/14/html/Storage_Administration_Guide/ch-swapspace.html Fedora documentation on swap] for a good overview on determining the right swap partition size.<br />
* 3: System - This will hold our root and home data. It will be formatted as BTRFS and will use subvolumes to manage snapshots of the current root and home contents.<br />
<br />
=== Visual overview of our partitions, filesystems, and contents ===<br />
<br />
This is a visual summary of our partions (inc. size information), encryption, filesystems, and a summary of the contents of each container.<br />
<br />
{| class="wikitable"<br />
| style="vertical-align: top; padding:1em" | '''Partition 1 (EFI)'''<br />
550MiB+<br />
{| style="border: 1px solid black; background: #DACEF2; margin: 1em;"<br />
! FAT32<br />
|-<br />
|kernel & initramfs<br />
(signed if using secure boot)<br />
|}<br />
| style="vertical-align: top; padding:1em" | '''Partition 2 (Swap)'''<br />
w/ Hibernate: Equal RAM,<br />
w/o Hibernate: min 8GB<br />
{| style="border: 1px solid black; background: #F2ECCE; margin: 1em;"<br />
|-<br />
! dm-crypt<br />
{| style="border: 1px solid black; background: #DACEF2; margin: 1em;"<br />
| SWAP<br />
|}<br />
|}<br />
| style="vertical-align: top; padding:1em" | '''Partition 3 (System)'''<br />
Remaining Space<br />
{| style="border: 1px solid black; background: #F2ECCE; margin: 1em;"<br />
|-<br />
! LUKS dm-crypt<br />
<br />
{| style="border: 1px solid black; background: #DACEF2; margin: 1em;"<br />
| BTRFS Top Level Subvolume<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Root Subvolume<br />
|}<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Home Subvolume<br />
|}<br />
<br />
{| style="border: 1px solid black; background: #E0CEF2; margin: 1em;"<br />
| BTRFS Snapshots Subvolume<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Root Snapshot Subvolume(s)<br />
|}<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Home Snapshot Subvolume(s)<br />
|}<br />
<br />
|}<br />
<br />
|}<br />
<br />
|}<br />
<br />
|}<br />
<br />
=== Partition Drive ===<br />
<br />
There are many utilities available for [[Partitioning]]. Because we are using Arch Linux and the command line doesn't hurt us (it makes us stronger) we will be using pure, non-interactive command line tools for this. Specifically, we will be using the utility [[Fdisk#Using_sgdisk|sgdisk]] from the {{Pkg|gptfdisk}} package. The [[Fdisk|fdisk]] utility now also supports GPT partitioned drives, so it would be an alternative. [[Fdisk#Using_sgdisk|sgdisk]] is available by default on the standard Arch install iso that you use to make your bootable USB drive.<br />
<br />
First, select the drive you will install to. Make sure you have selected the correct drive!. Again, a quick {{ic|lsblk}} will work here.<br />
<br />
# $DRIVE=/dev/DRIVEID<br />
<br />
(replace /dev/DRIVEID with the correct value, for example /dev/sda, /dev/nvme0n1, etc.)<br />
<br />
If you didn't securely wipe the drive already, it's worth "zapping" it using [[Fdisk#Using_sgdisk|sgdisk]] to remove any lingering legacy partition information. If you already wiped the drive you can skip this command (though it won't hurt to run it again).<br />
<br />
{{Warning|'''This command will also effectively erase the selected drive!'''}}<br />
<br />
# sgdisk --zap-all $DRIVE<br />
<br />
The following command will then create all three partitions in one go. '''It will also effectively erase the selected drive!'''<br />
<br />
# sgdisk --clear \<br />
--new=1:0:+550MiB --typecode=1:ef00 --change-name=1:EFI \<br />
--new=2:0:+8GiB --typecode=2:8200 --change-name=2:cryptswap \<br />
--new=3:0:0 --typecode=2:8200 --change-name=3:cryptsystem \<br />
$DRIVE<br />
<br />
It is worth noting that the "--change-name" values are, in this case, creating GPT "partition labels". You can subsequently see these by using the {{ic|lsblk -o +PARTLABEL}} command. It is good to use "EFI" for the efi partition. I am not aware of UEFI implementations that actively use the label for identification of the EFI partition, but it is possible that some do (UEFI bios implementations are not always consistent or to spec). The other two names are entirely "arbitrary". There is nothing special about calling them cryptswap and cryptsystem; they are simply good, clear names that remind us of the purpose of this partition and what it contains (for example, "cryptswap" suggests "this partition is for swap, and is encrypted").<br />
<br />
One final note about partition labels: we want them to be unique on your system. If for some reason there is already a GPT partition with the name EFI on another drive on your system, either change that partition name or use something besides "EFI" to avoid a namespace collision.<br />
<br />
Note also, that the backslashes at the end of each line can be omitted if you are writing the command on one long line instead. Those simply allow the splitting of a single command onto multiple lines.<br />
<br />
=== Format EFI Partition ===<br />
<br />
Next up: format the first (EFI) partition using the (required) FAT32 filesystem.<br />
<br />
# mksf.fat -F32 -n EFI /dev/disk/by-partlabel/EFI<br />
<br />
Note that we here make use of the partition label we just assigned. I prefer doing this since it simplifies scripts significantly for me and makes them, in my opinion, more readable.<br />
<br />
=== Encrypt System Partition ===<br />
<br />
Encrypt the main partition. Use a good passphrase. Note that the "--align-payload" value has been used as per [http://www.spinics.net/lists/dm-crypt/msg02421.html this suggestion/explanation] on the dm-crypt mailing list.<br />
<br />
Note also that I selected the encryption algorithm and key size using cryptsetup benchmark. See the [[Dm-crypt/Device_encryption]] article for more details.<br />
<br />
# cryptsetup luksFormat --align-payload=8192 -s 256 -c aes-xts-plain64 /dev/disk/by-partlabel/cryptsystem<br />
<br />
After creating the encrypted container, open it. Again, note the use of the partition label to identify the drive. Additionally, note that once we open this device we are giving it a name of "system." Thus "cryptsystem" is the encrypted system partition, while "system" is the name we are using once it has been opened in an unencrypted state. These names are arbitrary (Linux doesn't care what we use) but they help us keep things organized during this process.<br />
<br />
# cryptsetup open /dev/disk/by-partlabel/cryptsystem system<br />
<br />
=== Bring Up Encrypted Swap ===<br />
<br />
Finally we create encrypted swap. In this example we are not enabling hibernation. I will provide information on how to enable hibernation separately. Again, using partition labels to identify the partition and going from "cryptswap" to just "swap".<br />
<br />
We are not using LUKS here (which effectively makes dm-crypt easier to use). We're just using plain dm-crypt to encrypt the swap partition using a random key.<br />
<br />
# cryptsetup open --type plain --key-file /dev/urandom /dev/disk/by-partlabel/cryptswap swap<br />
# mkswap -L swap /dev/mapper/swap<br />
# swapon -L swap<br />
<br />
=== Create BTRFS Subvolumes ===<br />
<br />
Now on to the main attraction: creating our BTRFS subvolume structure. While BTRFS can be set up like any other filesystem (single command, just use the created file system directly), we're going to use the power of BTRFS to enable snapshotting our system state efficiently and rollbacks as necessary.<br />
<br />
First we create a top-level BTRFS subvolume. Note that the top-level entity in BTRFS nomenclature is still referred to as a '''sub'''volume, despite being at the top-level.<br />
<br />
We will create and mount this subvolume, create some new subvolumes inside it, and then switch to those subvolumes as our proper, mounted filesystems. Doing this will enable us to treat our root filesystem as a snapshotable object.<br />
<br />
Top-level subvolume creation.<br />
<br />
# mkfs.btrfs --force --label system /dev/mapper/system<br />
<br />
Temporarily mount our top-level volume for further subvolume creation. Note that the variable 'o' in this case is our default set of options for any given filesystem mount, while "o_btrfs" are those plus some options specific to btrfs. The default option "x-mount.mkdir" is a neat trick that allows us to skip the creation of directories for mountpoints (they will be created automatically). We assume /mnt as the standard mount point, as in a normal Arch Linux installation.<br />
<br />
# o=defaults,x-mount.mkdir<br />
# o_btrfs=$o,compress=lzo,ssd,noatime<br />
<br />
Note the use of our filesystem label to mount our subvolume. This is distinct from the partition labels used earlier. See the Arch wiki article on [[Persistent_block_device_naming]] for more information.<br />
<br />
# mount -t btrfs LABEL=system /mnt<br />
<br />
Now we create the subvolumes which will actually be mounted in our running system:<br />
<br />
# btrfs subvolume create /mnt/root<br />
# btrfs subvolume create /mnt/home<br />
# btrfs subvolume create /mnt/snapshots<br />
<br />
Then we unmount everything...<br />
<br />
# umount -R /mnt<br />
<br />
And remount just the subvolumes under our top-level subvolume (which remains unmounted unless we need to do "surgery" and rollback to a previous system system):<br />
<br />
# mount -t btrfs -o subvol=root,$o_btrfs LABEL=system /mnt<br />
<br />
Before mounting the home and snapshots subvolumes, let's walk through that command so we understand what it's doing:<br />
<br />
The 'mount -t btrfs' just specifies that our filesystem is of type BTRFS. This is often not necessary since mount will attempt to identify the filesystem type, but being explicit is often the best strategy with command line utilities, so we identify the type here.<br />
<br />
We use our previously defined mount options with the $o_btrfs variable and add the additional option "subvol=root" (separating it from our other defaults with a comma, of course). The next part of the command is "LABEL=system". Combined this reads as "mount the filesystem with the 'system' label, and use the 'root' subvolume within that".<br />
<br />
Finally, all this gets mounted at our install root, which in this case is "/mnt".<br />
<br />
Now let's pick back up and mount our home and snapshots subvolumes. Note that while the subvolume name is "snapshots", we will mount it at ".snapshots" (note dot prefix for the mount point). This will keep our root directory listing clean but will still make it available at a reasonable mount location.<br />
<br />
# mount -t btrfs -o subvol=home,$o_btrfs LABEL=system /mnt/home<br />
# mount -t btrfs -o subvol=snapshots,$o_btrfs LABEL=system /mnt/.snapshots<br />
<br />
It it worth noting that in each case we are telling mount to use the same filesystem, namely the one labeled "system". However in each case we are also telling it to look for a different subvolume in that filesystem (via the "subvol=" option).<br />
<br />
With this done, we can move on to installing the actual system.<br />
<br />
== Installation of Base Arch Linux System ==<br />
<br />
We are currently running off the Arch installer root filesystem. We will first use the 'pacstrap' utility to start our installation and then we will boot into our new minimal system using systemd-nspawn.<br />
<br />
=== Install base package group ===<br />
<br />
# pacstrap /mnt base<br />
<br />
=== fstab Generation and Modification ===<br />
<br />
{{Note|In a simpler, non encrypted configuration it is possible to skip making an fstab altogether due to a standard known as the [https://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/ Discoverable Partitions Spec]. However given the complexity of our encrypted, btrfs subvolume configuration, we require an fstab at this time. It is possible that in future we might feasibly do away with the fstab almost entirely in this setup (see the [https://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/#whataboutautomaticmountingofbtrfssubvolumestovarhomeandsoon 'What about automatic mounting of btrfs subvolumes'] section on that page).}}<br />
<br />
Create an [[fstab]] filesystem table file, using labels (-L) to identify the filesystems.<br />
<br />
# genfstab -L -p /mnt >> /mnt/etc/fstab<br />
<br />
I prefer to use labels as this makes the system more portable to a backup drive. You should end up with something that looks pretty close to this:<br />
<br />
{{hc|# cat /mnt/etc/fstab|<nowiki><br />
# /dev/mapper/system UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=system / btrfs rw,noatime,compress=lzo,ssd,space_cache,subvolid=257,subvol=/root,subvol=root 0 0<br />
<br />
# /dev/mapper/system UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=system /home btrfs rw,noatime,compress=lzo,ssd,space_cache,subvolid=258,subvol=/home,subvol=home 0 0<br />
<br />
# /dev/mapper/system UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=system /.snapshots btrfs rw,noatime,compress=lzo,ssd,space_cache,subvolid=259,subvol=/snapshots,subvol=snapshots 0 0<br />
<br />
# /dev/nvme0n1p1 UUID=xxxx-xxxx<br />
LABEL=EFI /boot/EFI vfat rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro 0 2<br />
<br />
# /dev/mapper/swap UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=swap none swap defaults 0 0<br />
</nowiki>}}<br />
<br />
There is one problem, however. Swap will not remount this way (the plain dm-crypt partition with a random key will not have a label when it is recreated on reboot). You will have to change that line from this:<br />
<br />
{{bc|<nowiki>LABEL=swap none swap defaults 0 0</nowiki>}}<br />
<br />
to this:<br />
<br />
{{bc|/dev/mapper/swap none swap defaults 0 0}}<br />
<br />
This will ensure that the mapped device is opened as swap successfully. The other lines may remain unchanged.<br />
<br />
==== Use {{ic|sed}} instead ====<br />
<br />
As a (scriptable) alternative to the manual editing of your {{ic|/etc/fstab}} you could use {{Man|1|sed}} to edit the file in place:<br />
<br />
# sed -i "s+LABEL=swap+/dev/mapper/swap" /etc/fstab_labels<br />
<br />
=== Boot into new system ===<br />
<br />
# systemd-nspawn -bD /mnt<br />
<br />
This will boot your new base Arch Linux system. After the standard boot messages scroll by you will be presented with a login (enter {{ic|root}} and hit enter to login).<br />
<br />
=== Generate and set locale ===<br />
<br />
Next, edit and uncomment your desired locale(s) from {{ic|/etc/locale.gen}}. We use {{ic|vi}} in the example below, but you could use a simpler editor such as {{ic|nano}} if you wish.<br />
<br />
{{hc|vi /etc/locale.gen|<nowiki><br />
...<br />
#en_PH.UTF-8 UTF-8<br />
#en_PH ISO-8859-1<br />
#en_SG.UTF-8 UTF-8<br />
#en_SG ISO-8859-1<br />
#en_US.UTF-8 UTF-8<br />
#en_US ISO-8859-1<br />
#en_ZA.UTF-8 UTF-8<br />
#en_ZA ISO-8859-1<br />
#en_ZM UTF-8<br />
...<br />
</nowiki>}}<br />
<br />
Changing it to (for en_US.UTF-8 as a locale in this example):<br />
<br />
{{bc|<nowiki><br />
...<br />
#en_PH.UTF-8 UTF-8<br />
#en_PH ISO-8859-1<br />
#en_SG.UTF-8 UTF-8<br />
#en_SG ISO-8859-1<br />
en_US.UTF-8 UTF-8<br />
#en_US ISO-8859-1<br />
#en_ZA.UTF-8 UTF-8<br />
#en_ZA ISO-8859-1<br />
#en_ZM UTF-8<br />
...<br />
</nowiki>}}<br />
<br />
Alternately one could simply append a known value to the {{ic|/etc/locale.gen}} file:<br />
<br />
# echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen<br />
<br />
After either method, one runs the {{ic|locale-gen}} command to generate the locale files:<br />
<br />
# locale-gen<br />
<br />
Finally we use {{Man|1|systemd-firstboot}} or {{Man|1|localectl}} to set the system locale. Each of these effectively does the same thing which is to simply write to {{ic|/etc/locale.conf}} (which can simply be edited directly as per standard Arch install instructions).<br />
<br />
==== With systemd-firstboot ====<br />
<br />
{{Man|1|systemd-firstboot}} will prompt us for selection from our generated locales. It will only work if there is no assigned system locale. If you wish to make changes afterward you can use {{Man|1|localectl}}<br />
<br />
# systemd-firstboot --prompt-locale<br />
<br />
==== With localectl ====<br />
<br />
This is an alternate to using {{ic|systemd-firstboot --prompt-locale}}. It may also be used subsequent to that command if further changes to the locale are desired.<br />
<br />
If you need a reminder of which locales have been installed (during this install or later during system changes), use {{ic|localectl list-locales}}:<br />
<br />
{{hc|<nowiki># localectl list-locales</nowiki>|en_US.UTF-8}}<br />
<br />
We then use {{ic|localectl set-locale}}:<br />
<br />
# localectl set-locale LANG=en_US.UTF-8<br />
<br />
=== Time and Date ===<br />
<br />
Unless you have a reason not to, we'll turn on NTP synchronization.<br />
<br />
# timedatectl set-ntp 1<br />
<br />
Then list timezones and pick one<br />
<br />
{{hc|<nowiki># timedatectl list-timezones</nowiki>|<nowiki><br />
...<br />
America/Kentucky/Louisville<br />
America/Kentucky/Monticello<br />
America/Kralendijk<br />
America/La_Paz<br />
America/Lima<br />
America/Los_Angeles<br />
America/Lower_Princes<br />
America/Maceio<br />
America/Managua<br />
America/Manaus<br />
America/Marigot<br />
America/Martinique<br />
America/Matamoros<br />
...<br />
</nowiki>}}<br />
# timedatectl set-timezone America/Los_Angeles<br />
<br />
=== Set hostname ===<br />
<br />
# hostnamectl set-hostname myhostname<br />
<br />
See the man page for {{Man|1|hostnamectl}} for other attributes that can be set. You might also add the hostname to {{Man|5|hosts}}:<br />
<br />
{{hc|/etc/hosts|<br />
127.0.0.1 localhost.localdomain localhost<br />
::1 localhost.localdomain localhost<br />
'''127.0.1.1 ''myhostname''.localdomain ''myhostname'''''<br />
}}<br />
<br />
Use {{ic|echo}} for a scriptable solution:<br />
<br />
# echo "127.0.1.1 myhostname.localdomain myhostname" >> /etc/hosts<br />
<br />
=== Network configuration ===<br />
<br />
Configure the network for the newly installed environment: see [[Network configuration]].<br />
<br />
For [[Wireless configuration]], [[Help:Reading#Installation of packages|install]] the {{Pkg|iw}}, {{Pkg|wpa_supplicant}}, and {{Pkg|dialog}} packages, as well as needed [[Wireless#Installing driver/firmware|firmware packages]].<br />
<br />
=== Base Package Installation ===<br />
<br />
We've already included the {{Grp|base}} group which is, strictly speaking, all you need to boot a minimal Arch Linux system. At this stage, however, we can install some useful utilities (and Xorg or Wayland, etc.).<br />
<br />
# pacman -Syu base-devel btrfs-progs iw gptfdisk zsh vim terminus-font<br />
<br />
=== Initramfs ===<br />
<br />
Creating a new ''initramfs'' is usually not required, because [[mkinitcpio]] was run on installation of the {{Pkg|linux}} package with ''pacstrap''.<br />
<br />
For special configurations, modify the {{man|5|mkinitcpio.conf|url=}} file and recreate the initramfs image:<br />
<br />
# mkinitcpio -p linux<br />
<br />
=== Bootloader ===<br />
<br />
{{Warning|THIS SECTION IN PROGRESS}}<br />
<br />
=== Root password ===<br />
<br />
Set the root [[password]]:<br />
<br />
# passwd<br />
<br />
=== Leave the systemd-nspawn environment ===<br />
<br />
Issue a poweroff to exit the nspawned environment:<br />
<br />
# poweroff<br />
<br />
This will return you the Arch installer environment where you can wrap up.<br />
<br />
=== Legacy boot loader ===<br />
<br />
If your system is not UEFI and you need to use a legacy installer like grub, it will need to be installed from within an arch-chroot generated chroot, not the systemd-nspawn running container. An example of this would be (assuming that the drive of the new system is at /dev/sdb):<br />
<br />
# arch-chroot /mnt<br />
# grub-install $DRIVE<br />
# grub-mkconfig -o /boot/grub/grub.cfg<br />
# exit<br />
<br />
== Command Summary ==<br />
<br />
The following are all critical commands (exluded: the initial drive wipe which is optional). It assumes you have successfully brought up networking prior to starting this sequence.<br />
<br />
{{bc|<nowiki><br />
<br />
$DRIVE=/dev/DRIVEID<br />
<br />
sgdisk --zap-all $DRIVE<br />
<br />
sgdisk --clear \<br />
--new=1:0:+550MiB --typecode=1:ef00 --change-name=1:EFI \<br />
--new=2:0:+8GiB --typecode=2:8200 --change-name=2:cryptswap \<br />
--new=3:0:0 --typecode=2:8200 --change-name=3:cryptsystem \<br />
$DRIVE<br />
<br />
mksf.fat -F32 -n EFI /dev/disk/by-partlabel/EFI<br />
<br />
cryptsetup luksFormat --align-payload=8192 -s 256 -c aes-xts-plain64 /dev/disk/by-partlabel/cryptsystem<br />
<br />
cryptsetup open /dev/disk/by-partlabel/cryptsystem system<br />
<br />
cryptsetup open --type plain --key-file /dev/urandom /dev/disk/by-partlabel/cryptswap swap<br />
<br />
mkswap -L swap /dev/mapper/swap<br />
<br />
swapon -L swap<br />
<br />
mkfs.btrfs --force --label system /dev/mapper/system<br />
<br />
o=defaults,x-mount.mkdir<br />
<br />
o_btrfs=$o,compress=lzo,ssd,noatime<br />
<br />
mount -t btrfs LABEL=system /mnt<br />
<br />
btrfs subvolume create /mnt/root<br />
<br />
btrfs subvolume create /mnt/home<br />
<br />
btrfs subvolume create /mnt/snapshots<br />
<br />
umount -R /mnt<br />
<br />
mount -t btrfs -o subvol=root,$o_btrfs LABEL=system /mnt<br />
<br />
mount -t btrfs -o subvol=home,$o_btrfs LABEL=system /mnt/home<br />
<br />
mount -t btrfs -o subvol=snapshots,$o_btrfs LABEL=system /mnt/.snapshots<br />
<br />
pacstrap /mnt base<br />
<br />
genfstab -L -p /mnt >> /mnt/etc/fstab<br />
<br />
sed -i "s+LABEL=swap+/dev/mapper/swap" /etc/fstab_labels<br />
<br />
systemd-nspawn -bD /mnt<br />
<br />
echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen<br />
<br />
locale-gen<br />
<br />
localectl set-locale LANG=en_US.UTF-8<br />
<br />
timedatectl set-ntp 1<br />
<br />
timedatectl set-timezone America/Los_Angeles<br />
<br />
hostnamectl set-hostname myhostname<br />
<br />
echo "127.0.1.1 myhostname.localdomain myhostname" >> /etc/hosts<br />
<br />
pacman -Syu base-devel btrfs-progs iw gptfdisk zsh vim terminus-font<br />
</nowiki>}}<br />
<br />
== Extra: Sample "quick and dirty" Arch install using systemd-nspawn ==<br />
<br />
This is the approximate process I follow if I want to bring up Arch on, say, an old laptop for a quick purpose built test machine, etc. It's not an install that I consider long term maintainable since rollbacks aren't implemented, nor is there any encryption, but it's a good example of how simple installation can be.<br />
<br />
{{bc|<nowiki><br />
$DRIVE=/dev/DRIVEID<br />
sgdisk --zap-all $DRIVE<br />
mkfs.btrfs -f $DRIVE<br />
mount -t btrfs $DRIVE /mnt<br />
pacstrap /mnt base<br />
systemd-nspawn -bD /mnt<br />
echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen<br />
locale-gen<br />
localectl set-locale LANG=en_US.UTF-8<br />
timedatectl set-ntp 1<br />
timedatectl set-timezone America/Los_Angeles<br />
hostnamectl set-hostname myhostname<br />
poweroff<br />
arch-chroot /mnt<br />
grub-install --root-directory=/mnt $DRIVE<br />
grub-mkconfig -o /mnt/boot/grub/grub.cfg<br />
exit<br />
reboot<br />
</nowiki>}}</div>Altercationhttps://wiki.archlinux.org/index.php?title=User:Altercation/Bullet_Proof_Arch_Install&diff=458566User:Altercation/Bullet Proof Arch Install2016-12-05T23:11:59Z<p>Altercation: /* Extra: Sample "quick and dirty" Arch install using systemd-nspawn */</p>
<hr />
<div>This page is a summary of the current process I follow when installing Arch on a new laptop or desktop. My process varies over time, but this serves as my "state of the art" best practice recommendations. I'm open to feedback and suggestions for improvements.<br />
<br />
{{Note|This is entirely based on my own opinions and research. It is opinionated about the best way to do things given the current state of the kernel, hardware availability, and utilities, filesystems, etc. I will explain my rationale for specific choices and provide links to other sources of information (on the Arch wiki or external) where useful.}}<br />
<br />
== Objectives ==<br />
<br />
The goals of my standard "bullet proof" Arch Linux installation are:<br />
<br />
* Benefit from Arch's rolling release model while mitigating any risk of system corruption or data loss due to failed upgrades<br />
* Minimize risk due to hardware failure or total system loss (e.g. theft or physical destruction)<br />
* Make system rollbacks easy and procedural, using a standard setup and methodology for recovery of previous system (and user data) states<br />
<br />
=== Why not the Arch Install instructions? ===<br />
<br />
The [[Installation guide|Arch Linux installation instructions]] are an excellent, general starting point and you should read and understand them. That being said, they are designed to map to a very, very broad set of installation scenarios. I am interested in a very specific type of installation (daily use desktops and laptops in this article) and I have a strong set of opinions about the "right" or "best practice" way to set up my own working systems.<br />
<br />
These instructions, then, are much more prescriptive and have strong suggestions or directions about how (and why) one should use a particular method during Arch Linux installation.<br />
<br />
=== Key differences from the stock Arch install instructions ===<br />
<br />
How these instructions differ from the standard Arch guidance:<br />
<br />
* We are encrypting the entire system but not using LVM as is often recommended (see the encryption section below for details about why we are not using it).<br />
* I use labels and avoid UUIDs where possible to make switching to an alternate recovery drive easier.<br />
* I skip arch-chroot and simply boot the new system ('''not''' reboot, just boot) from within the install environment using {{Man|1|systemd-nspawn}} which enables the *ctl commands to work (and systemd services to be enabled properly without need for a system reboot)<br />
* I use the various systemd *ctl commands (hostnamectl, timedatectl, localectl, etc.) to configure the system<br />
* I use the systemd mkinitcpio hooks in lieu of the legacy hooks.<br />
* I use BTRFS exclusively for root and home partitions for its backup capabilities.<br />
* I recommend and use secure boot (but not with the Microsoft keys) to minimize risk due to the unavoidably unencrypted EFI partition.<br />
<br />
== Assumptions ==<br />
<br />
These instructions presuppose the following:<br />
<br />
* fairly new hardware (these instructions may work on older hardware, but there may be unusual issues that crop up... if you aren't comfortable handling those situations you should consider a more "traditional" Arch Linux install (e.g. using grub, LVM, ext4, etc.)<br />
* [[Unified Extensible Firmware Interface|UEFI support]] (BIOS system install is also possible with some modification of these instructions, but this has not yet been detailed here)<br />
* probably an [[Solid State Drives|SSD]].<br />
* some familiarity with Arch, or at least some experience with Linux, will help<br />
<br />
{{Warning|I am assuming you are going to single boot (not dual boot) and that you are '''willing to wipe all data from the install drive.''' If that is not the case, do not proceed with these instructions as following them '''will effectively destroy any data (and other operating systems) on the installation target drive.'''}}<br />
<br />
== Prerequisites ==<br />
<br />
You must have a recent copy of the Arch install USB. See [[:Category:Getting and installing Arch]] for general information and [[USB flash installation media]] for specific details on creating a USB Arch installation drive.<br />
<br />
You should also have a reasonable amount of time in which to complete the installation. Novice users will want to budget a couple hours. Experienced users will ''know'' to budget a couple hours.<br />
<br />
== Preparation ==<br />
<br />
=== Boot from USB Drive ===<br />
<br />
Boot your system from your prepared [[USB flash installation media|Arch Linux USB drive]]. It is important that you boot in EFI mode, not legacy BIOS compatibility mode. See the [[Unified Extensible Firmware Interface|UEFI]] article for more information about checking boot mode and ensuring you are booting using EFI.<br />
<br />
=== Bring up the network ===<br />
<br />
If you booted into a system with an ethernet cable plugged in, chances are you're up and running. If you need to use wireless instead, {{ic|wifi-menu}} will more often than not work without trouble. If those don't work, see [[Installation guide#Connect to the Internet|the Arch installation guide section on connecting to the internet]].<br />
<br />
=== Select Drive ===<br />
<br />
I like to use the [[Core utilities#lsblk|{{ic|1=lsblk}}]] command to bring up a quick list of the block devices on the system and identify existing partition structures and sizes, as well as mount points. If you don't already use it, I recommend [[Core utilities#lsblk|{{ic|1=lsblk}}]] when you need information on any given drive or partition. It's useful for polling UUIDs as well. For example, the following command gives you a clearly formatted summary of all block devices, their partition labels, filesystem lables, UUIDs and partition UUIDS: {{ic|lsblk -o +LABEL,PARTLABEL,UUID,PARTUUID}}<br />
<br />
In any case, the plain command without options should be enough to identify the drive you will install to (for example {{ic|1=/dev/sda}} or {{ic|1=/dev/nvme0n1}}:<br />
<br />
# lsblk<br />
<br />
=== Wipe Drive Securely (optional) ===<br />
<br />
While it is not necessary, given that this process will go through the trouble of encrypting the main system partition, it makes sense to do a secure wipe of the drive. This is more or less directly from [[Dm-crypt/Drive preparation#dm-crypt wipe on an empty disk or partition]].<br />
<br />
{{Warning|Be certain of your target device selection as we will be '''wiping this drive''' (either securely or, at minimum, destroying all existing partition data).}}<br />
<br />
First, create a temporary encrypted container the full disk ({{ic|sdX}}) to be encrypted, e.g. using default encryption parameters and a random key via the {{ic|--key-file /dev/{u}random}} option (see also [[Random number generation]]):<br />
<br />
# cryptsetup open --type plain /dev/sdXY container --key-file /dev/urandom<br />
<br />
{{Note|An interesting page addressing myths about /dev/urandom can be [http://www.2uo.de/myths-about-urandom/ found here]}}<br />
<br />
Second, check the container exists:<br />
<br />
{{hc|# fdisk -l|Disk /dev/mapper/container: XXXX MB, XXXXXXXXXX bytes<br />
...<br />
Disk /dev/mapper/container does not contain a valid partition table}}<br />
Wipe the container with zeros. A use of {{ic|1=if=/dev/urandom}} is '''not''' required as the encryption cipher itself generates randomness.<br />
{{hc|# dd <nowiki>if=/dev/zero of=/dev/mapper/container status=progress bs=1M</nowiki>|<br />
dd: writing to ‘/dev/mapper/container’: No space left on device}}<br />
<br />
{{Tip|<br />
* Using ''dd'' with the {{ic|1=bs=}} option, e.g. {{ic|1=bs=1M}} as above, is frequently used to increase disk throughput of the operation.<br />
* To perform a check of the operation, zero the partition before creating the wipe container. After the wipe command {{ic|blockdev --getsize64 ''/dev/mapper/container''}} can be used to get the exact container size as root. Now ''od'' can be used to spotcheck whether the wipe overwrote the zeroed sectors, e.g. {{ic|od -j ''containersize - blocksize''}} to view the wipe completed to the end.}}<br />
<br />
Finally, close the temporary container:<br />
<br />
# cryptsetup close container<br />
<br />
== Partition & Format Drive ==<br />
<br />
=== Understanding some basics about disks, partitions, and filesystems ===<br />
<br />
Think of your drive like a big empty building, no rooms. This is your plain physical drive (either a spinning platter drive or an SSD). Next imagine that to make it useful, we divide the building into apartments. In our analogy the apartments are '''partitions''' of the drive.<br />
<br />
Imagine also that there are a couple different standard methods of creating layout maps to the apartments. These plans are standardized so that the public services that have to access the building regularly (like the fire and police, for example) understand how to find the apartment entrances. In the world of partitioning, the equivalent is the "partition table scheme". The two common schemes are called "MBR" (Master Boot Record, older) and "GPT" (GUID Partition Table, newer). We will be using the new GPT scheme.<br />
<br />
Finally, imagine that the apartments are just empty shells. The act of building walls and laying out the functional structure of the apartments is equivalent to formatting our disk partitions with a filesystem. And just as different layouts may be more or less efficient, or have other different functional characteristics, so to filesystems have different attributes that make them useful in different ways.<br />
<br />
=== Our partition plans ===<br />
<br />
We will take our physical drive and divide it into three partitions. These partitions each serve a distinct purpose. All but the first and smallest, the EFI partition, will be encrypted. For security, if your system supports Secure Boot, you may choose to cryptographically sign the data stored on the EFI partition so that any tampering will be evident, despite the lack of encryption on that partition.<br />
<br />
{{Note|Again, we're assuming an UEFI installation (not legacy BIOS) and a GPT (not MBR) partition structure. If none of that made sense, best to start with the [[Partitioning]] article or do some test installs of Arch first. '''Partitioning is, in my opinion, one of the areas that is most confusing for the new Arch user.''' Additionally, there is a lot "received wisdom" and cargo-cult assumption making about how best to partition. Working through some of the "this is how it's always been done" tutorials isn't necessarily a bad thing... In many cases the way it has always been done has some sound reasoning behind it, despite being cargo-culted half the time. That being said, the method presented here is different from that in most of the Arch wiki partitioning methodologies.}}<br />
<br />
We will not be using LVM. You read a lot about LUKS and LVM and it all gets a bit complicated (LVM on LUKS, LUKS on LVM, etc.). LVM is a "logical volume manager" and abstracts physical devices (drives) into virtual devices, for easier management. It's a good idea but we will be using btrfs to effectively achieve the same results and really don't need the overhead of LVM.<br />
<br />
=== Partition Summary ===<br />
<br />
* 1: EFI - The UEFI 'bios" will look for this FAT32 formatted partition and either locate a default bootloader or will locate a specific EFI boot entry on it. This partition is by necessity not encrypted (unless the drive it is on has been encrypted as a "self encrypting drive")<br />
* 2: Swap - Used by Linux to swap out pages of memory from RAM to disk. Despite debate in this area, it is advisable to have at least some swap space, even it you are not planning on using hibernation on your machine. The Arch wiki is unfortunately rather too brief in its own [[Swap|swap article]] so I recommend the [https://docs.fedoraproject.org/en-US/Fedora/14/html/Storage_Administration_Guide/ch-swapspace.html Fedora documentation on swap] for a good overview on determining the right swap partition size.<br />
* 3: System - This will hold our root and home data. It will be formatted as BTRFS and will use subvolumes to manage snapshots of the current root and home contents.<br />
<br />
=== Visual overview of our partitions, filesystems, and contents ===<br />
<br />
This is a visual summary of our partions (inc. size information), encryption, filesystems, and a summary of the contents of each container.<br />
<br />
{| class="wikitable"<br />
| style="vertical-align: top; padding:1em" | '''Partition 1 (EFI)'''<br />
550MiB+<br />
{| style="border: 1px solid black; background: #DACEF2; margin: 1em;"<br />
! FAT32<br />
|-<br />
|kernel & initramfs<br />
(signed if using secure boot)<br />
|}<br />
| style="vertical-align: top; padding:1em" | '''Partition 2 (Swap)'''<br />
w/ Hibernate: Equal RAM,<br />
w/o Hibernate: min 8GB<br />
{| style="border: 1px solid black; background: #F2ECCE; margin: 1em;"<br />
|-<br />
! dm-crypt<br />
{| style="border: 1px solid black; background: #DACEF2; margin: 1em;"<br />
| SWAP<br />
|}<br />
|}<br />
| style="vertical-align: top; padding:1em" | '''Partition 3 (System)'''<br />
Remaining Space<br />
{| style="border: 1px solid black; background: #F2ECCE; margin: 1em;"<br />
|-<br />
! LUKS dm-crypt<br />
<br />
{| style="border: 1px solid black; background: #DACEF2; margin: 1em;"<br />
| BTRFS Top Level Subvolume<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Root Subvolume<br />
|}<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Home Subvolume<br />
|}<br />
<br />
{| style="border: 1px solid black; background: #E0CEF2; margin: 1em;"<br />
| BTRFS Snapshots Subvolume<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Root Snapshot Subvolume(s)<br />
|}<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Home Snapshot Subvolume(s)<br />
|}<br />
<br />
|}<br />
<br />
|}<br />
<br />
|}<br />
<br />
|}<br />
<br />
=== Partition Drive ===<br />
<br />
There are many utilities available for [[Partitioning]]. Because we are using Arch Linux and the command line doesn't hurt us (it makes us stronger) we will be using pure, non-interactive command line tools for this. Specifically, we will be using the utility [[Fdisk#Using_sgdisk|sgdisk]] from the {{Pkg|gptfdisk}} package. The [[Fdisk|fdisk]] utility now also supports GPT partitioned drives, so it would be an alternative. [[Fdisk#Using_sgdisk|sgdisk]] is available by default on the standard Arch install iso that you use to make your bootable USB drive.<br />
<br />
First, select the drive you will install to. Make sure you have selected the correct drive!. Again, a quick {{ic|lsblk}} will work here.<br />
<br />
# $DRIVE=/dev/DRIVEID<br />
<br />
(replace /dev/DRIVEID with the correct value, for example /dev/sda, /dev/nvme0n1, etc.)<br />
<br />
If you didn't securely wipe the drive already, it's worth "zapping" it using [[Fdisk#Using_sgdisk|sgdisk]] to remove any lingering legacy partition information. If you already wiped the drive you can skip this command (though it won't hurt to run it again).<br />
<br />
{{Warning|'''This command will also effectively erase the selected drive!'''}}<br />
<br />
# sgdisk --zap-all $DRIVE<br />
<br />
The following command will then create all three partitions in one go. '''It will also effectively erase the selected drive!'''<br />
<br />
# sgdisk --clear \<br />
--new=1:0:+550MiB --typecode=1:ef00 --change-name=1:EFI \<br />
--new=2:0:+8GiB --typecode=2:8200 --change-name=2:cryptswap \<br />
--new=3:0:0 --typecode=2:8200 --change-name=3:cryptsystem \<br />
$DRIVE<br />
<br />
It is worth noting that the "--change-name" values are, in this case, creating GPT "partition labels". You can subsequently see these by using the {{ic|lsblk -o +PARTLABEL}} command. It is good to use "EFI" for the efi partition. I am not aware of UEFI implementations that actively use the label for identification of the EFI partition, but it is possible that some do (UEFI bios implementations are not always consistent or to spec). The other two names are entirely "arbitrary". There is nothing special about calling them cryptswap and cryptsystem; they are simply good, clear names that remind us of the purpose of this partition and what it contains (for example, "cryptswap" suggests "this partition is for swap, and is encrypted").<br />
<br />
One final note about partition labels: we want them to be unique on your system. If for some reason there is already a GPT partition with the name EFI on another drive on your system, either change that partition name or use something besides "EFI" to avoid a namespace collision.<br />
<br />
Note also, that the backslashes at the end of each line can be omitted if you are writing the command on one long line instead. Those simply allow the splitting of a single command onto multiple lines.<br />
<br />
=== Format EFI Partition ===<br />
<br />
Next up: format the first (EFI) partition using the (required) FAT32 filesystem.<br />
<br />
# mksf.fat -F32 -n EFI /dev/disk/by-partlabel/EFI<br />
<br />
Note that we here make use of the partition label we just assigned. I prefer doing this since it simplifies scripts significantly for me and makes them, in my opinion, more readable.<br />
<br />
=== Encrypt System Partition ===<br />
<br />
Encrypt the main partition. Use a good passphrase. Note that the "--align-payload" value has been used as per [http://www.spinics.net/lists/dm-crypt/msg02421.html this suggestion/explanation] on the dm-crypt mailing list.<br />
<br />
Note also that I selected the encryption algorithm and key size using cryptsetup benchmark. See the [[Dm-crypt/Device_encryption]] article for more details.<br />
<br />
# cryptsetup luksFormat --align-payload=8192 -s 256 -c aes-xts-plain64 /dev/disk/by-partlabel/cryptsystem<br />
<br />
After creating the encrypted container, open it. Again, note the use of the partition label to identify the drive. Additionally, note that once we open this device we are giving it a name of "system." Thus "cryptsystem" is the encrypted system partition, while "system" is the name we are using once it has been opened in an unencrypted state. These names are arbitrary (Linux doesn't care what we use) but they help us keep things organized during this process.<br />
<br />
# cryptsetup open /dev/disk/by-partlabel/cryptsystem system<br />
<br />
=== Bring Up Encrypted Swap ===<br />
<br />
Finally we create encrypted swap. In this example we are not enabling hibernation. I will provide information on how to enable hibernation separately. Again, using partition labels to identify the partition and going from "cryptswap" to just "swap".<br />
<br />
We are not using LUKS here (which effectively makes dm-crypt easier to use). We're just using plain dm-crypt to encrypt the swap partition using a random key.<br />
<br />
# cryptsetup open --type plain --key-file /dev/urandom /dev/disk/by-partlabel/cryptswap swap<br />
# mkswap -L swap /dev/mapper/swap<br />
# swapon -L swap<br />
<br />
=== Create BTRFS Subvolumes ===<br />
<br />
Now on to the main attraction: creating our BTRFS subvolume structure. While BTRFS can be set up like any other filesystem (single command, just use the created file system directly), we're going to use the power of BTRFS to enable snapshotting our system state efficiently and rollbacks as necessary.<br />
<br />
First we create a top-level BTRFS subvolume. Note that the top-level entity in BTRFS nomenclature is still referred to as a '''sub'''volume, despite being at the top-level.<br />
<br />
We will create and mount this subvolume, create some new subvolumes inside it, and then switch to those subvolumes as our proper, mounted filesystems. Doing this will enable us to treat our root filesystem as a snapshotable object.<br />
<br />
Top-level subvolume creation.<br />
<br />
# mkfs.btrfs --force --label system /dev/mapper/system<br />
<br />
Temporarily mount our top-level volume for further subvolume creation. Note that the variable 'o' in this case is our default set of options for any given filesystem mount, while "o_btrfs" are those plus some options specific to btrfs. The default option "x-mount.mkdir" is a neat trick that allows us to skip the creation of directories for mountpoints (they will be created automatically). We assume /mnt as the standard mount point, as in a normal Arch Linux installation.<br />
<br />
# o=defaults,x-mount.mkdir<br />
# o_btrfs=$o,compress=lzo,ssd,noatime<br />
<br />
Note the use of our filesystem label to mount our subvolume. This is distinct from the partition labels used earlier. See the Arch wiki article on [[Persistent_block_device_naming]] for more information.<br />
<br />
# mount -t btrfs LABEL=system /mnt<br />
<br />
Now we create the subvolumes which will actually be mounted in our running system:<br />
<br />
# btrfs subvolume create /mnt/root<br />
# btrfs subvolume create /mnt/home<br />
# btrfs subvolume create /mnt/snapshots<br />
<br />
Then we unmount everything...<br />
<br />
# umount -R /mnt<br />
<br />
And remount just the subvolumes under our top-level subvolume (which remains unmounted unless we need to do "surgery" and rollback to a previous system system):<br />
<br />
# mount -t btrfs -o subvol=root,$o_btrfs LABEL=system /mnt<br />
<br />
Before mounting the home and snapshots subvolumes, let's walk through that command so we understand what it's doing:<br />
<br />
The 'mount -t btrfs' just specifies that our filesystem is of type BTRFS. This is often not necessary since mount will attempt to identify the filesystem type, but being explicit is often the best strategy with command line utilities, so we identify the type here.<br />
<br />
We use our previously defined mount options with the $o_btrfs variable and add the additional option "subvol=root" (separating it from our other defaults with a comma, of course). The next part of the command is "LABEL=system". Combined this reads as "mount the filesystem with the 'system' label, and use the 'root' subvolume within that".<br />
<br />
Finally, all this gets mounted at our install root, which in this case is "/mnt".<br />
<br />
Now let's pick back up and mount our home and snapshots subvolumes. Note that while the subvolume name is "snapshots", we will mount it at ".snapshots" (note dot prefix for the mount point). This will keep our root directory listing clean but will still make it available at a reasonable mount location.<br />
<br />
# mount -t btrfs -o subvol=home,$o_btrfs LABEL=system /mnt/home<br />
# mount -t btrfs -o subvol=snapshots,$o_btrfs LABEL=system /mnt/.snapshots<br />
<br />
It it worth noting that in each case we are telling mount to use the same filesystem, namely the one labeled "system". However in each case we are also telling it to look for a different subvolume in that filesystem (via the "subvol=" option).<br />
<br />
With this done, we can move on to installing the actual system.<br />
<br />
== Installation of Base Arch Linux System ==<br />
<br />
We are currently running off the Arch installer root filesystem. We will first use the 'pacstrap' utility to start our installation and then we will boot into our new minimal system using systemd-nspawn.<br />
<br />
=== Install base package group ===<br />
<br />
# pacstrap /mnt base<br />
<br />
=== fstab Generation and Modification ===<br />
<br />
{{Note|In a simpler, non encrypted configuration it is possible to skip making an fstab altogether due to a standard known as the [https://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/ Discoverable Partitions Spec]. However given the complexity of our encrypted, btrfs subvolume configuration, we require an fstab at this time. It is possible that in future we might feasibly do away with the fstab almost entirely in this setup (see the [https://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/#whataboutautomaticmountingofbtrfssubvolumestovarhomeandsoon 'What about automatic mounting of btrfs subvolumes'] section on that page).}}<br />
<br />
Create an [[fstab]] filesystem table file, using labels (-L) to identify the filesystems.<br />
<br />
# genfstab -L -p /mnt >> /mnt/etc/fstab<br />
<br />
I prefer to use labels as this makes the system more portable to a backup drive. You should end up with something that looks pretty close to this:<br />
<br />
{{hc|# cat /mnt/etc/fstab|<nowiki><br />
# /dev/mapper/system UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=system / btrfs rw,noatime,compress=lzo,ssd,space_cache,subvolid=257,subvol=/root,subvol=root 0 0<br />
<br />
# /dev/mapper/system UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=system /home btrfs rw,noatime,compress=lzo,ssd,space_cache,subvolid=258,subvol=/home,subvol=home 0 0<br />
<br />
# /dev/mapper/system UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=system /.snapshots btrfs rw,noatime,compress=lzo,ssd,space_cache,subvolid=259,subvol=/snapshots,subvol=snapshots 0 0<br />
<br />
# /dev/nvme0n1p1 UUID=xxxx-xxxx<br />
LABEL=EFI /boot/EFI vfat rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro 0 2<br />
<br />
# /dev/mapper/swap UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=swap none swap defaults 0 0<br />
</nowiki>}}<br />
<br />
There is one problem, however. Swap will not remount this way (the plain dm-crypt partition with a random key will not have a label when it is recreated on reboot). You will have to change that line from this:<br />
<br />
{{bc|<nowiki>LABEL=swap none swap defaults 0 0</nowiki>}}<br />
<br />
to this:<br />
<br />
{{bc|/dev/mapper/swap none swap defaults 0 0}}<br />
<br />
This will ensure that the mapped device is opened as swap successfully. The other lines may remain unchanged.<br />
<br />
==== Use {{ic|sed}} instead ====<br />
<br />
As a (scriptable) alternative to the manual editing of your {{ic|/etc/fstab}} you could use {{Man|1|sed}} to edit the file in place:<br />
<br />
# sed -i "s+LABEL=swap+/dev/mapper/swap" /etc/fstab_labels<br />
<br />
=== Boot into new system ===<br />
<br />
# systemd-nspawn -bD /mnt<br />
<br />
This will boot your new base Arch Linux system. After the standard boot messages scroll by you will be presented with a login (enter {{ic|root}} and hit enter to login).<br />
<br />
=== Generate and set locale ===<br />
<br />
Next, edit and uncomment your desired locale(s) from {{ic|/etc/locale.gen}}. We use {{ic|vi}} in the example below, but you could use a simpler editor such as {{ic|nano}} if you wish.<br />
<br />
{{hc|vi /etc/locale.gen|<nowiki><br />
...<br />
#en_PH.UTF-8 UTF-8<br />
#en_PH ISO-8859-1<br />
#en_SG.UTF-8 UTF-8<br />
#en_SG ISO-8859-1<br />
#en_US.UTF-8 UTF-8<br />
#en_US ISO-8859-1<br />
#en_ZA.UTF-8 UTF-8<br />
#en_ZA ISO-8859-1<br />
#en_ZM UTF-8<br />
...<br />
</nowiki>}}<br />
<br />
Changing it to (for en_US.UTF-8 as a locale in this example):<br />
<br />
{{bc|<nowiki><br />
...<br />
#en_PH.UTF-8 UTF-8<br />
#en_PH ISO-8859-1<br />
#en_SG.UTF-8 UTF-8<br />
#en_SG ISO-8859-1<br />
en_US.UTF-8 UTF-8<br />
#en_US ISO-8859-1<br />
#en_ZA.UTF-8 UTF-8<br />
#en_ZA ISO-8859-1<br />
#en_ZM UTF-8<br />
...<br />
</nowiki>}}<br />
<br />
Alternately one could simply append a known value to the {{ic|/etc/locale.gen}} file:<br />
<br />
# echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen<br />
<br />
After either method, one runs the {{ic|locale-gen}} command to generate the locale files:<br />
<br />
# locale-gen<br />
<br />
Finally we use {{Man|1|systemd-firstboot}} or {{Man|1|localectl}} to set the system locale. Each of these effectively does the same thing which is to simply write to {{ic|/etc/locale.conf}} (which can simply be edited directly as per standard Arch install instructions).<br />
<br />
==== With systemd-firstboot ====<br />
<br />
{{Man|1|systemd-firstboot}} will prompt us for selection from our generated locales. It will only work if there is no assigned system locale. If you wish to make changes afterward you can use {{Man|1|localectl}}<br />
<br />
# systemd-firstboot --prompt-locale<br />
<br />
==== With localectl ====<br />
<br />
This is an alternate to using {{ic|systemd-firstboot --prompt-locale}}. It may also be used subsequent to that command if further changes to the locale are desired.<br />
<br />
If you need a reminder of which locales have been installed (during this install or later during system changes), use {{ic|localectl list-locales}}:<br />
<br />
{{hc|<nowiki># localectl list-locales</nowiki>|en_US.UTF-8}}<br />
<br />
We then use {{ic|localectl set-locale}}:<br />
<br />
# localectl set-locale LANG=en_US.UTF-8<br />
<br />
=== Time and Date ===<br />
<br />
Unless you have a reason not to, we'll turn on NTP synchronization.<br />
<br />
# timedatectl set-ntp 1<br />
<br />
Then list timezones and pick one<br />
<br />
{{hc|<nowiki># timedatectl list-timezones</nowiki>|<nowiki><br />
...<br />
America/Kentucky/Louisville<br />
America/Kentucky/Monticello<br />
America/Kralendijk<br />
America/La_Paz<br />
America/Lima<br />
America/Los_Angeles<br />
America/Lower_Princes<br />
America/Maceio<br />
America/Managua<br />
America/Manaus<br />
America/Marigot<br />
America/Martinique<br />
America/Matamoros<br />
...<br />
</nowiki>}}<br />
# timedatectl set-timezone America/Los_Angeles<br />
<br />
=== Set hostname ===<br />
<br />
# hostnamectl set-hostname myhostname<br />
<br />
See the man page for {{Man|1|hostnamectl}} for other attributes that can be set. You might also add the hostname to {{Man|5|hosts}}:<br />
<br />
{{hc|/etc/hosts|<br />
127.0.0.1 localhost.localdomain localhost<br />
::1 localhost.localdomain localhost<br />
'''127.0.1.1 ''myhostname''.localdomain ''myhostname'''''<br />
}}<br />
<br />
Use {{ic|echo}} for a scriptable solution:<br />
<br />
# echo "127.0.1.1 myhostname.localdomain myhostname" >> /etc/hosts<br />
<br />
=== Network configuration ===<br />
<br />
Configure the network for the newly installed environment: see [[Network configuration]].<br />
<br />
For [[Wireless configuration]], [[Help:Reading#Installation of packages|install]] the {{Pkg|iw}}, {{Pkg|wpa_supplicant}}, and {{Pkg|dialog}} packages, as well as needed [[Wireless#Installing driver/firmware|firmware packages]].<br />
<br />
=== Base Package Installation ===<br />
<br />
We've already included the {{Grp|base}} group which is, strictly speaking, all you need to boot a minimal Arch Linux system. At this stage, however, we can install some useful utilities (and Xorg or Wayland, etc.).<br />
<br />
# pacman -Syu base-devel btrfs-progs iw gptfdisk zsh vim terminus-font<br />
<br />
=== Initramfs ===<br />
<br />
Creating a new ''initramfs'' is usually not required, because [[mkinitcpio]] was run on installation of the {{Pkg|linux}} package with ''pacstrap''.<br />
<br />
For special configurations, modify the {{man|5|mkinitcpio.conf|url=}} file and recreate the initramfs image:<br />
<br />
# mkinitcpio -p linux<br />
<br />
=== Bootloader ===<br />
<br />
{{Warning|THIS SECTION IN PROGRESS}}<br />
<br />
=== Root password ===<br />
<br />
Set the root [[password]]:<br />
<br />
# passwd<br />
<br />
=== Leave the systemd-nspawn environment ===<br />
<br />
Issue a poweroff to exit the nspawned environment:<br />
<br />
# poweroff<br />
<br />
This will return you the Arch installer environment where you can wrap up.<br />
<br />
=== Legacy boot loader ===<br />
<br />
If your system is not UEFI and you need to use a legacy installer like grub, it will need to be installed from the Arch installer environment, not the systemd-nspawn fresh install. An example of this would be (assuming that the drive of the new system is at /dev/sdb):<br />
<br />
# grub-install --root-directory=/mnt /dev/sdb<br />
# grub-mkconfig -o /mnt/boot/grub/grub.cfg<br />
<br />
== Command Summary ==<br />
<br />
The following are all critical commands (exluded: the initial drive wipe which is optional). It assumes you have successfully brought up networking prior to starting this sequence.<br />
<br />
{{bc|<nowiki><br />
<br />
$DRIVE=/dev/DRIVEID<br />
<br />
sgdisk --zap-all $DRIVE<br />
<br />
sgdisk --clear \<br />
--new=1:0:+550MiB --typecode=1:ef00 --change-name=1:EFI \<br />
--new=2:0:+8GiB --typecode=2:8200 --change-name=2:cryptswap \<br />
--new=3:0:0 --typecode=2:8200 --change-name=3:cryptsystem \<br />
$DRIVE<br />
<br />
mksf.fat -F32 -n EFI /dev/disk/by-partlabel/EFI<br />
<br />
cryptsetup luksFormat --align-payload=8192 -s 256 -c aes-xts-plain64 /dev/disk/by-partlabel/cryptsystem<br />
<br />
cryptsetup open /dev/disk/by-partlabel/cryptsystem system<br />
<br />
cryptsetup open --type plain --key-file /dev/urandom /dev/disk/by-partlabel/cryptswap swap<br />
<br />
mkswap -L swap /dev/mapper/swap<br />
<br />
swapon -L swap<br />
<br />
mkfs.btrfs --force --label system /dev/mapper/system<br />
<br />
o=defaults,x-mount.mkdir<br />
<br />
o_btrfs=$o,compress=lzo,ssd,noatime<br />
<br />
mount -t btrfs LABEL=system /mnt<br />
<br />
btrfs subvolume create /mnt/root<br />
<br />
btrfs subvolume create /mnt/home<br />
<br />
btrfs subvolume create /mnt/snapshots<br />
<br />
umount -R /mnt<br />
<br />
mount -t btrfs -o subvol=root,$o_btrfs LABEL=system /mnt<br />
<br />
mount -t btrfs -o subvol=home,$o_btrfs LABEL=system /mnt/home<br />
<br />
mount -t btrfs -o subvol=snapshots,$o_btrfs LABEL=system /mnt/.snapshots<br />
<br />
pacstrap /mnt base<br />
<br />
genfstab -L -p /mnt >> /mnt/etc/fstab<br />
<br />
sed -i "s+LABEL=swap+/dev/mapper/swap" /etc/fstab_labels<br />
<br />
systemd-nspawn -bD /mnt<br />
<br />
echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen<br />
<br />
locale-gen<br />
<br />
localectl set-locale LANG=en_US.UTF-8<br />
<br />
timedatectl set-ntp 1<br />
<br />
timedatectl set-timezone America/Los_Angeles<br />
<br />
hostnamectl set-hostname myhostname<br />
<br />
echo "127.0.1.1 myhostname.localdomain myhostname" >> /etc/hosts<br />
<br />
pacman -Syu base-devel btrfs-progs iw gptfdisk zsh vim terminus-font<br />
</nowiki>}}<br />
<br />
== Extra: Sample "quick and dirty" Arch install using systemd-nspawn ==<br />
<br />
This is the approximate process I follow if I want to bring up Arch on, say, an old laptop for a quick purpose built test machine, etc. It's not an install that I consider long term maintainable since rollbacks aren't implemented, nor is there any encryption, but it's a good example of how simple installation can be.<br />
<br />
{{bc|<nowiki><br />
$DRIVE=/dev/DRIVEID<br />
sgdisk --zap-all $DRIVE<br />
mkfs.btrfs -f $DRIVE<br />
mount -t btrfs $DRIVE /mnt<br />
pacstrap /mnt base<br />
systemd-nspawn -bD /mnt<br />
echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen<br />
locale-gen<br />
localectl set-locale LANG=en_US.UTF-8<br />
timedatectl set-ntp 1<br />
timedatectl set-timezone America/Los_Angeles<br />
hostnamectl set-hostname myhostname<br />
poweroff<br />
arch-chroot /mnt<br />
grub-install --root-directory=/mnt $DRIVE<br />
grub-mkconfig -o /mnt/boot/grub/grub.cfg<br />
exit<br />
reboot<br />
</nowiki>}}</div>Altercationhttps://wiki.archlinux.org/index.php?title=User:Altercation/Bullet_Proof_Arch_Install&diff=458563User:Altercation/Bullet Proof Arch Install2016-12-05T22:51:19Z<p>Altercation: </p>
<hr />
<div>This page is a summary of the current process I follow when installing Arch on a new laptop or desktop. My process varies over time, but this serves as my "state of the art" best practice recommendations. I'm open to feedback and suggestions for improvements.<br />
<br />
{{Note|This is entirely based on my own opinions and research. It is opinionated about the best way to do things given the current state of the kernel, hardware availability, and utilities, filesystems, etc. I will explain my rationale for specific choices and provide links to other sources of information (on the Arch wiki or external) where useful.}}<br />
<br />
== Objectives ==<br />
<br />
The goals of my standard "bullet proof" Arch Linux installation are:<br />
<br />
* Benefit from Arch's rolling release model while mitigating any risk of system corruption or data loss due to failed upgrades<br />
* Minimize risk due to hardware failure or total system loss (e.g. theft or physical destruction)<br />
* Make system rollbacks easy and procedural, using a standard setup and methodology for recovery of previous system (and user data) states<br />
<br />
=== Why not the Arch Install instructions? ===<br />
<br />
The [[Installation guide|Arch Linux installation instructions]] are an excellent, general starting point and you should read and understand them. That being said, they are designed to map to a very, very broad set of installation scenarios. I am interested in a very specific type of installation (daily use desktops and laptops in this article) and I have a strong set of opinions about the "right" or "best practice" way to set up my own working systems.<br />
<br />
These instructions, then, are much more prescriptive and have strong suggestions or directions about how (and why) one should use a particular method during Arch Linux installation.<br />
<br />
=== Key differences from the stock Arch install instructions ===<br />
<br />
How these instructions differ from the standard Arch guidance:<br />
<br />
* We are encrypting the entire system but not using LVM as is often recommended (see the encryption section below for details about why we are not using it).<br />
* I use labels and avoid UUIDs where possible to make switching to an alternate recovery drive easier.<br />
* I skip arch-chroot and simply boot the new system ('''not''' reboot, just boot) from within the install environment using {{Man|1|systemd-nspawn}} which enables the *ctl commands to work (and systemd services to be enabled properly without need for a system reboot)<br />
* I use the various systemd *ctl commands (hostnamectl, timedatectl, localectl, etc.) to configure the system<br />
* I use the systemd mkinitcpio hooks in lieu of the legacy hooks.<br />
* I use BTRFS exclusively for root and home partitions for its backup capabilities.<br />
* I recommend and use secure boot (but not with the Microsoft keys) to minimize risk due to the unavoidably unencrypted EFI partition.<br />
<br />
== Assumptions ==<br />
<br />
These instructions presuppose the following:<br />
<br />
* fairly new hardware (these instructions may work on older hardware, but there may be unusual issues that crop up... if you aren't comfortable handling those situations you should consider a more "traditional" Arch Linux install (e.g. using grub, LVM, ext4, etc.)<br />
* [[Unified Extensible Firmware Interface|UEFI support]] (BIOS system install is also possible with some modification of these instructions, but this has not yet been detailed here)<br />
* probably an [[Solid State Drives|SSD]].<br />
* some familiarity with Arch, or at least some experience with Linux, will help<br />
<br />
{{Warning|I am assuming you are going to single boot (not dual boot) and that you are '''willing to wipe all data from the install drive.''' If that is not the case, do not proceed with these instructions as following them '''will effectively destroy any data (and other operating systems) on the installation target drive.'''}}<br />
<br />
== Prerequisites ==<br />
<br />
You must have a recent copy of the Arch install USB. See [[:Category:Getting and installing Arch]] for general information and [[USB flash installation media]] for specific details on creating a USB Arch installation drive.<br />
<br />
You should also have a reasonable amount of time in which to complete the installation. Novice users will want to budget a couple hours. Experienced users will ''know'' to budget a couple hours.<br />
<br />
== Preparation ==<br />
<br />
=== Boot from USB Drive ===<br />
<br />
Boot your system from your prepared [[USB flash installation media|Arch Linux USB drive]]. It is important that you boot in EFI mode, not legacy BIOS compatibility mode. See the [[Unified Extensible Firmware Interface|UEFI]] article for more information about checking boot mode and ensuring you are booting using EFI.<br />
<br />
=== Bring up the network ===<br />
<br />
If you booted into a system with an ethernet cable plugged in, chances are you're up and running. If you need to use wireless instead, {{ic|wifi-menu}} will more often than not work without trouble. If those don't work, see [[Installation guide#Connect to the Internet|the Arch installation guide section on connecting to the internet]].<br />
<br />
=== Select Drive ===<br />
<br />
I like to use the [[Core utilities#lsblk|{{ic|1=lsblk}}]] command to bring up a quick list of the block devices on the system and identify existing partition structures and sizes, as well as mount points. If you don't already use it, I recommend [[Core utilities#lsblk|{{ic|1=lsblk}}]] when you need information on any given drive or partition. It's useful for polling UUIDs as well. For example, the following command gives you a clearly formatted summary of all block devices, their partition labels, filesystem lables, UUIDs and partition UUIDS: {{ic|lsblk -o +LABEL,PARTLABEL,UUID,PARTUUID}}<br />
<br />
In any case, the plain command without options should be enough to identify the drive you will install to (for example {{ic|1=/dev/sda}} or {{ic|1=/dev/nvme0n1}}:<br />
<br />
# lsblk<br />
<br />
=== Wipe Drive Securely (optional) ===<br />
<br />
While it is not necessary, given that this process will go through the trouble of encrypting the main system partition, it makes sense to do a secure wipe of the drive. This is more or less directly from [[Dm-crypt/Drive preparation#dm-crypt wipe on an empty disk or partition]].<br />
<br />
{{Warning|Be certain of your target device selection as we will be '''wiping this drive''' (either securely or, at minimum, destroying all existing partition data).}}<br />
<br />
First, create a temporary encrypted container the full disk ({{ic|sdX}}) to be encrypted, e.g. using default encryption parameters and a random key via the {{ic|--key-file /dev/{u}random}} option (see also [[Random number generation]]):<br />
<br />
# cryptsetup open --type plain /dev/sdXY container --key-file /dev/urandom<br />
<br />
{{Note|An interesting page addressing myths about /dev/urandom can be [http://www.2uo.de/myths-about-urandom/ found here]}}<br />
<br />
Second, check the container exists:<br />
<br />
{{hc|# fdisk -l|Disk /dev/mapper/container: XXXX MB, XXXXXXXXXX bytes<br />
...<br />
Disk /dev/mapper/container does not contain a valid partition table}}<br />
Wipe the container with zeros. A use of {{ic|1=if=/dev/urandom}} is '''not''' required as the encryption cipher itself generates randomness.<br />
{{hc|# dd <nowiki>if=/dev/zero of=/dev/mapper/container status=progress bs=1M</nowiki>|<br />
dd: writing to ‘/dev/mapper/container’: No space left on device}}<br />
<br />
{{Tip|<br />
* Using ''dd'' with the {{ic|1=bs=}} option, e.g. {{ic|1=bs=1M}} as above, is frequently used to increase disk throughput of the operation.<br />
* To perform a check of the operation, zero the partition before creating the wipe container. After the wipe command {{ic|blockdev --getsize64 ''/dev/mapper/container''}} can be used to get the exact container size as root. Now ''od'' can be used to spotcheck whether the wipe overwrote the zeroed sectors, e.g. {{ic|od -j ''containersize - blocksize''}} to view the wipe completed to the end.}}<br />
<br />
Finally, close the temporary container:<br />
<br />
# cryptsetup close container<br />
<br />
== Partition & Format Drive ==<br />
<br />
=== Understanding some basics about disks, partitions, and filesystems ===<br />
<br />
Think of your drive like a big empty building, no rooms. This is your plain physical drive (either a spinning platter drive or an SSD). Next imagine that to make it useful, we divide the building into apartments. In our analogy the apartments are '''partitions''' of the drive.<br />
<br />
Imagine also that there are a couple different standard methods of creating layout maps to the apartments. These plans are standardized so that the public services that have to access the building regularly (like the fire and police, for example) understand how to find the apartment entrances. In the world of partitioning, the equivalent is the "partition table scheme". The two common schemes are called "MBR" (Master Boot Record, older) and "GPT" (GUID Partition Table, newer). We will be using the new GPT scheme.<br />
<br />
Finally, imagine that the apartments are just empty shells. The act of building walls and laying out the functional structure of the apartments is equivalent to formatting our disk partitions with a filesystem. And just as different layouts may be more or less efficient, or have other different functional characteristics, so to filesystems have different attributes that make them useful in different ways.<br />
<br />
=== Our partition plans ===<br />
<br />
We will take our physical drive and divide it into three partitions. These partitions each serve a distinct purpose. All but the first and smallest, the EFI partition, will be encrypted. For security, if your system supports Secure Boot, you may choose to cryptographically sign the data stored on the EFI partition so that any tampering will be evident, despite the lack of encryption on that partition.<br />
<br />
{{Note|Again, we're assuming an UEFI installation (not legacy BIOS) and a GPT (not MBR) partition structure. If none of that made sense, best to start with the [[Partitioning]] article or do some test installs of Arch first. '''Partitioning is, in my opinion, one of the areas that is most confusing for the new Arch user.''' Additionally, there is a lot "received wisdom" and cargo-cult assumption making about how best to partition. Working through some of the "this is how it's always been done" tutorials isn't necessarily a bad thing... In many cases the way it has always been done has some sound reasoning behind it, despite being cargo-culted half the time. That being said, the method presented here is different from that in most of the Arch wiki partitioning methodologies.}}<br />
<br />
We will not be using LVM. You read a lot about LUKS and LVM and it all gets a bit complicated (LVM on LUKS, LUKS on LVM, etc.). LVM is a "logical volume manager" and abstracts physical devices (drives) into virtual devices, for easier management. It's a good idea but we will be using btrfs to effectively achieve the same results and really don't need the overhead of LVM.<br />
<br />
=== Partition Summary ===<br />
<br />
* 1: EFI - The UEFI 'bios" will look for this FAT32 formatted partition and either locate a default bootloader or will locate a specific EFI boot entry on it. This partition is by necessity not encrypted (unless the drive it is on has been encrypted as a "self encrypting drive")<br />
* 2: Swap - Used by Linux to swap out pages of memory from RAM to disk. Despite debate in this area, it is advisable to have at least some swap space, even it you are not planning on using hibernation on your machine. The Arch wiki is unfortunately rather too brief in its own [[Swap|swap article]] so I recommend the [https://docs.fedoraproject.org/en-US/Fedora/14/html/Storage_Administration_Guide/ch-swapspace.html Fedora documentation on swap] for a good overview on determining the right swap partition size.<br />
* 3: System - This will hold our root and home data. It will be formatted as BTRFS and will use subvolumes to manage snapshots of the current root and home contents.<br />
<br />
=== Visual overview of our partitions, filesystems, and contents ===<br />
<br />
This is a visual summary of our partions (inc. size information), encryption, filesystems, and a summary of the contents of each container.<br />
<br />
{| class="wikitable"<br />
| style="vertical-align: top; padding:1em" | '''Partition 1 (EFI)'''<br />
550MiB+<br />
{| style="border: 1px solid black; background: #DACEF2; margin: 1em;"<br />
! FAT32<br />
|-<br />
|kernel & initramfs<br />
(signed if using secure boot)<br />
|}<br />
| style="vertical-align: top; padding:1em" | '''Partition 2 (Swap)'''<br />
w/ Hibernate: Equal RAM,<br />
w/o Hibernate: min 8GB<br />
{| style="border: 1px solid black; background: #F2ECCE; margin: 1em;"<br />
|-<br />
! dm-crypt<br />
{| style="border: 1px solid black; background: #DACEF2; margin: 1em;"<br />
| SWAP<br />
|}<br />
|}<br />
| style="vertical-align: top; padding:1em" | '''Partition 3 (System)'''<br />
Remaining Space<br />
{| style="border: 1px solid black; background: #F2ECCE; margin: 1em;"<br />
|-<br />
! LUKS dm-crypt<br />
<br />
{| style="border: 1px solid black; background: #DACEF2; margin: 1em;"<br />
| BTRFS Top Level Subvolume<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Root Subvolume<br />
|}<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Home Subvolume<br />
|}<br />
<br />
{| style="border: 1px solid black; background: #E0CEF2; margin: 1em;"<br />
| BTRFS Snapshots Subvolume<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Root Snapshot Subvolume(s)<br />
|}<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Home Snapshot Subvolume(s)<br />
|}<br />
<br />
|}<br />
<br />
|}<br />
<br />
|}<br />
<br />
|}<br />
<br />
=== Partition Drive ===<br />
<br />
There are many utilities available for [[Partitioning]]. Because we are using Arch Linux and the command line doesn't hurt us (it makes us stronger) we will be using pure, non-interactive command line tools for this. Specifically, we will be using the utility [[Fdisk#Using_sgdisk|sgdisk]] from the {{Pkg|gptfdisk}} package. The [[Fdisk|fdisk]] utility now also supports GPT partitioned drives, so it would be an alternative. [[Fdisk#Using_sgdisk|sgdisk]] is available by default on the standard Arch install iso that you use to make your bootable USB drive.<br />
<br />
First, select the drive you will install to. Make sure you have selected the correct drive!. Again, a quick {{ic|lsblk}} will work here.<br />
<br />
# $DRIVE=/dev/DRIVEID<br />
<br />
(replace /dev/DRIVEID with the correct value, for example /dev/sda, /dev/nvme0n1, etc.)<br />
<br />
If you didn't securely wipe the drive already, it's worth "zapping" it using [[Fdisk#Using_sgdisk|sgdisk]] to remove any lingering legacy partition information. If you already wiped the drive you can skip this command (though it won't hurt to run it again).<br />
<br />
{{Warning|'''This command will also effectively erase the selected drive!'''}}<br />
<br />
# sgdisk --zap-all $DRIVE<br />
<br />
The following command will then create all three partitions in one go. '''It will also effectively erase the selected drive!'''<br />
<br />
# sgdisk --clear \<br />
--new=1:0:+550MiB --typecode=1:ef00 --change-name=1:EFI \<br />
--new=2:0:+8GiB --typecode=2:8200 --change-name=2:cryptswap \<br />
--new=3:0:0 --typecode=2:8200 --change-name=3:cryptsystem \<br />
$DRIVE<br />
<br />
It is worth noting that the "--change-name" values are, in this case, creating GPT "partition labels". You can subsequently see these by using the {{ic|lsblk -o +PARTLABEL}} command. It is good to use "EFI" for the efi partition. I am not aware of UEFI implementations that actively use the label for identification of the EFI partition, but it is possible that some do (UEFI bios implementations are not always consistent or to spec). The other two names are entirely "arbitrary". There is nothing special about calling them cryptswap and cryptsystem; they are simply good, clear names that remind us of the purpose of this partition and what it contains (for example, "cryptswap" suggests "this partition is for swap, and is encrypted").<br />
<br />
One final note about partition labels: we want them to be unique on your system. If for some reason there is already a GPT partition with the name EFI on another drive on your system, either change that partition name or use something besides "EFI" to avoid a namespace collision.<br />
<br />
Note also, that the backslashes at the end of each line can be omitted if you are writing the command on one long line instead. Those simply allow the splitting of a single command onto multiple lines.<br />
<br />
=== Format EFI Partition ===<br />
<br />
Next up: format the first (EFI) partition using the (required) FAT32 filesystem.<br />
<br />
# mksf.fat -F32 -n EFI /dev/disk/by-partlabel/EFI<br />
<br />
Note that we here make use of the partition label we just assigned. I prefer doing this since it simplifies scripts significantly for me and makes them, in my opinion, more readable.<br />
<br />
=== Encrypt System Partition ===<br />
<br />
Encrypt the main partition. Use a good passphrase. Note that the "--align-payload" value has been used as per [http://www.spinics.net/lists/dm-crypt/msg02421.html this suggestion/explanation] on the dm-crypt mailing list.<br />
<br />
Note also that I selected the encryption algorithm and key size using cryptsetup benchmark. See the [[Dm-crypt/Device_encryption]] article for more details.<br />
<br />
# cryptsetup luksFormat --align-payload=8192 -s 256 -c aes-xts-plain64 /dev/disk/by-partlabel/cryptsystem<br />
<br />
After creating the encrypted container, open it. Again, note the use of the partition label to identify the drive. Additionally, note that once we open this device we are giving it a name of "system." Thus "cryptsystem" is the encrypted system partition, while "system" is the name we are using once it has been opened in an unencrypted state. These names are arbitrary (Linux doesn't care what we use) but they help us keep things organized during this process.<br />
<br />
# cryptsetup open /dev/disk/by-partlabel/cryptsystem system<br />
<br />
=== Bring Up Encrypted Swap ===<br />
<br />
Finally we create encrypted swap. In this example we are not enabling hibernation. I will provide information on how to enable hibernation separately. Again, using partition labels to identify the partition and going from "cryptswap" to just "swap".<br />
<br />
We are not using LUKS here (which effectively makes dm-crypt easier to use). We're just using plain dm-crypt to encrypt the swap partition using a random key.<br />
<br />
# cryptsetup open --type plain --key-file /dev/urandom /dev/disk/by-partlabel/cryptswap swap<br />
# mkswap -L swap /dev/mapper/swap<br />
# swapon -L swap<br />
<br />
=== Create BTRFS Subvolumes ===<br />
<br />
Now on to the main attraction: creating our BTRFS subvolume structure. While BTRFS can be set up like any other filesystem (single command, just use the created file system directly), we're going to use the power of BTRFS to enable snapshotting our system state efficiently and rollbacks as necessary.<br />
<br />
First we create a top-level BTRFS subvolume. Note that the top-level entity in BTRFS nomenclature is still referred to as a '''sub'''volume, despite being at the top-level.<br />
<br />
We will create and mount this subvolume, create some new subvolumes inside it, and then switch to those subvolumes as our proper, mounted filesystems. Doing this will enable us to treat our root filesystem as a snapshotable object.<br />
<br />
Top-level subvolume creation.<br />
<br />
# mkfs.btrfs --force --label system /dev/mapper/system<br />
<br />
Temporarily mount our top-level volume for further subvolume creation. Note that the variable 'o' in this case is our default set of options for any given filesystem mount, while "o_btrfs" are those plus some options specific to btrfs. The default option "x-mount.mkdir" is a neat trick that allows us to skip the creation of directories for mountpoints (they will be created automatically). We assume /mnt as the standard mount point, as in a normal Arch Linux installation.<br />
<br />
# o=defaults,x-mount.mkdir<br />
# o_btrfs=$o,compress=lzo,ssd,noatime<br />
<br />
Note the use of our filesystem label to mount our subvolume. This is distinct from the partition labels used earlier. See the Arch wiki article on [[Persistent_block_device_naming]] for more information.<br />
<br />
# mount -t btrfs LABEL=system /mnt<br />
<br />
Now we create the subvolumes which will actually be mounted in our running system:<br />
<br />
# btrfs subvolume create /mnt/root<br />
# btrfs subvolume create /mnt/home<br />
# btrfs subvolume create /mnt/snapshots<br />
<br />
Then we unmount everything...<br />
<br />
# umount -R /mnt<br />
<br />
And remount just the subvolumes under our top-level subvolume (which remains unmounted unless we need to do "surgery" and rollback to a previous system system):<br />
<br />
# mount -t btrfs -o subvol=root,$o_btrfs LABEL=system /mnt<br />
<br />
Before mounting the home and snapshots subvolumes, let's walk through that command so we understand what it's doing:<br />
<br />
The 'mount -t btrfs' just specifies that our filesystem is of type BTRFS. This is often not necessary since mount will attempt to identify the filesystem type, but being explicit is often the best strategy with command line utilities, so we identify the type here.<br />
<br />
We use our previously defined mount options with the $o_btrfs variable and add the additional option "subvol=root" (separating it from our other defaults with a comma, of course). The next part of the command is "LABEL=system". Combined this reads as "mount the filesystem with the 'system' label, and use the 'root' subvolume within that".<br />
<br />
Finally, all this gets mounted at our install root, which in this case is "/mnt".<br />
<br />
Now let's pick back up and mount our home and snapshots subvolumes. Note that while the subvolume name is "snapshots", we will mount it at ".snapshots" (note dot prefix for the mount point). This will keep our root directory listing clean but will still make it available at a reasonable mount location.<br />
<br />
# mount -t btrfs -o subvol=home,$o_btrfs LABEL=system /mnt/home<br />
# mount -t btrfs -o subvol=snapshots,$o_btrfs LABEL=system /mnt/.snapshots<br />
<br />
It it worth noting that in each case we are telling mount to use the same filesystem, namely the one labeled "system". However in each case we are also telling it to look for a different subvolume in that filesystem (via the "subvol=" option).<br />
<br />
With this done, we can move on to installing the actual system.<br />
<br />
== Installation of Base Arch Linux System ==<br />
<br />
We are currently running off the Arch installer root filesystem. We will first use the 'pacstrap' utility to start our installation and then we will boot into our new minimal system using systemd-nspawn.<br />
<br />
=== Install base package group ===<br />
<br />
# pacstrap /mnt base<br />
<br />
=== fstab Generation and Modification ===<br />
<br />
{{Note|In a simpler, non encrypted configuration it is possible to skip making an fstab altogether due to a standard known as the [https://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/ Discoverable Partitions Spec]. However given the complexity of our encrypted, btrfs subvolume configuration, we require an fstab at this time. It is possible that in future we might feasibly do away with the fstab almost entirely in this setup (see the [https://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/#whataboutautomaticmountingofbtrfssubvolumestovarhomeandsoon 'What about automatic mounting of btrfs subvolumes'] section on that page).}}<br />
<br />
Create an [[fstab]] filesystem table file, using labels (-L) to identify the filesystems.<br />
<br />
# genfstab -L -p /mnt >> /mnt/etc/fstab<br />
<br />
I prefer to use labels as this makes the system more portable to a backup drive. You should end up with something that looks pretty close to this:<br />
<br />
{{hc|# cat /mnt/etc/fstab|<nowiki><br />
# /dev/mapper/system UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=system / btrfs rw,noatime,compress=lzo,ssd,space_cache,subvolid=257,subvol=/root,subvol=root 0 0<br />
<br />
# /dev/mapper/system UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=system /home btrfs rw,noatime,compress=lzo,ssd,space_cache,subvolid=258,subvol=/home,subvol=home 0 0<br />
<br />
# /dev/mapper/system UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=system /.snapshots btrfs rw,noatime,compress=lzo,ssd,space_cache,subvolid=259,subvol=/snapshots,subvol=snapshots 0 0<br />
<br />
# /dev/nvme0n1p1 UUID=xxxx-xxxx<br />
LABEL=EFI /boot/EFI vfat rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro 0 2<br />
<br />
# /dev/mapper/swap UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=swap none swap defaults 0 0<br />
</nowiki>}}<br />
<br />
There is one problem, however. Swap will not remount this way (the plain dm-crypt partition with a random key will not have a label when it is recreated on reboot). You will have to change that line from this:<br />
<br />
{{bc|<nowiki>LABEL=swap none swap defaults 0 0</nowiki>}}<br />
<br />
to this:<br />
<br />
{{bc|/dev/mapper/swap none swap defaults 0 0}}<br />
<br />
This will ensure that the mapped device is opened as swap successfully. The other lines may remain unchanged.<br />
<br />
==== Use {{ic|sed}} instead ====<br />
<br />
As a (scriptable) alternative to the manual editing of your {{ic|/etc/fstab}} you could use {{Man|1|sed}} to edit the file in place:<br />
<br />
# sed -i "s+LABEL=swap+/dev/mapper/swap" /etc/fstab_labels<br />
<br />
=== Boot into new system ===<br />
<br />
# systemd-nspawn -bD /mnt<br />
<br />
This will boot your new base Arch Linux system. After the standard boot messages scroll by you will be presented with a login (enter {{ic|root}} and hit enter to login).<br />
<br />
=== Generate and set locale ===<br />
<br />
Next, edit and uncomment your desired locale(s) from {{ic|/etc/locale.gen}}. We use {{ic|vi}} in the example below, but you could use a simpler editor such as {{ic|nano}} if you wish.<br />
<br />
{{hc|vi /etc/locale.gen|<nowiki><br />
...<br />
#en_PH.UTF-8 UTF-8<br />
#en_PH ISO-8859-1<br />
#en_SG.UTF-8 UTF-8<br />
#en_SG ISO-8859-1<br />
#en_US.UTF-8 UTF-8<br />
#en_US ISO-8859-1<br />
#en_ZA.UTF-8 UTF-8<br />
#en_ZA ISO-8859-1<br />
#en_ZM UTF-8<br />
...<br />
</nowiki>}}<br />
<br />
Changing it to (for en_US.UTF-8 as a locale in this example):<br />
<br />
{{bc|<nowiki><br />
...<br />
#en_PH.UTF-8 UTF-8<br />
#en_PH ISO-8859-1<br />
#en_SG.UTF-8 UTF-8<br />
#en_SG ISO-8859-1<br />
en_US.UTF-8 UTF-8<br />
#en_US ISO-8859-1<br />
#en_ZA.UTF-8 UTF-8<br />
#en_ZA ISO-8859-1<br />
#en_ZM UTF-8<br />
...<br />
</nowiki>}}<br />
<br />
Alternately one could simply append a known value to the {{ic|/etc/locale.gen}} file:<br />
<br />
# echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen<br />
<br />
After either method, one runs the {{ic|locale-gen}} command to generate the locale files:<br />
<br />
# locale-gen<br />
<br />
Finally we use {{Man|1|systemd-firstboot}} or {{Man|1|localectl}} to set the system locale. Each of these effectively does the same thing which is to simply write to {{ic|/etc/locale.conf}} (which can simply be edited directly as per standard Arch install instructions).<br />
<br />
==== With systemd-firstboot ====<br />
<br />
{{Man|1|systemd-firstboot}} will prompt us for selection from our generated locales. It will only work if there is no assigned system locale. If you wish to make changes afterward you can use {{Man|1|localectl}}<br />
<br />
# systemd-firstboot --prompt-locale<br />
<br />
==== With localectl ====<br />
<br />
This is an alternate to using {{ic|systemd-firstboot --prompt-locale}}. It may also be used subsequent to that command if further changes to the locale are desired.<br />
<br />
If you need a reminder of which locales have been installed (during this install or later during system changes), use {{ic|localectl list-locales}}:<br />
<br />
{{hc|<nowiki># localectl list-locales</nowiki>|en_US.UTF-8}}<br />
<br />
We then use {{ic|localectl set-locale}}:<br />
<br />
# localectl set-locale LANG=en_US.UTF-8<br />
<br />
=== Time and Date ===<br />
<br />
Unless you have a reason not to, we'll turn on NTP synchronization.<br />
<br />
# timedatectl set-ntp 1<br />
<br />
Then list timezones and pick one<br />
<br />
{{hc|<nowiki># timedatectl list-timezones</nowiki>|<nowiki><br />
...<br />
America/Kentucky/Louisville<br />
America/Kentucky/Monticello<br />
America/Kralendijk<br />
America/La_Paz<br />
America/Lima<br />
America/Los_Angeles<br />
America/Lower_Princes<br />
America/Maceio<br />
America/Managua<br />
America/Manaus<br />
America/Marigot<br />
America/Martinique<br />
America/Matamoros<br />
...<br />
</nowiki>}}<br />
# timedatectl set-timezone America/Los_Angeles<br />
<br />
=== Set hostname ===<br />
<br />
# hostnamectl set-hostname myhostname<br />
<br />
See the man page for {{Man|1|hostnamectl}} for other attributes that can be set. You might also add the hostname to {{Man|5|hosts}}:<br />
<br />
{{hc|/etc/hosts|<br />
127.0.0.1 localhost.localdomain localhost<br />
::1 localhost.localdomain localhost<br />
'''127.0.1.1 ''myhostname''.localdomain ''myhostname'''''<br />
}}<br />
<br />
Use {{ic|echo}} for a scriptable solution:<br />
<br />
# echo "127.0.1.1 myhostname.localdomain myhostname" >> /etc/hosts<br />
<br />
=== Network configuration ===<br />
<br />
Configure the network for the newly installed environment: see [[Network configuration]].<br />
<br />
For [[Wireless configuration]], [[Help:Reading#Installation of packages|install]] the {{Pkg|iw}}, {{Pkg|wpa_supplicant}}, and {{Pkg|dialog}} packages, as well as needed [[Wireless#Installing driver/firmware|firmware packages]].<br />
<br />
=== Base Package Installation ===<br />
<br />
We've already included the {{Grp|base}} group which is, strictly speaking, all you need to boot a minimal Arch Linux system. At this stage, however, we can install some useful utilities (and Xorg or Wayland, etc.).<br />
<br />
# pacman -Syu base-devel btrfs-progs iw gptfdisk zsh vim terminus-font<br />
<br />
=== Initramfs ===<br />
<br />
Creating a new ''initramfs'' is usually not required, because [[mkinitcpio]] was run on installation of the {{Pkg|linux}} package with ''pacstrap''.<br />
<br />
For special configurations, modify the {{man|5|mkinitcpio.conf|url=}} file and recreate the initramfs image:<br />
<br />
# mkinitcpio -p linux<br />
<br />
=== Bootloader ===<br />
<br />
{{Warning|THIS SECTION IN PROGRESS}}<br />
<br />
=== Root password ===<br />
<br />
Set the root [[password]]:<br />
<br />
# passwd<br />
<br />
=== Leave the systemd-nspawn environment ===<br />
<br />
Issue a poweroff to exit the nspawned environment:<br />
<br />
# poweroff<br />
<br />
This will return you the Arch installer environment where you can wrap up.<br />
<br />
=== Legacy boot loader ===<br />
<br />
If your system is not UEFI and you need to use a legacy installer like grub, it will need to be installed from the Arch installer environment, not the systemd-nspawn fresh install. An example of this would be (assuming that the drive of the new system is at /dev/sdb):<br />
<br />
# grub-install --root-directory=/mnt /dev/sdb<br />
# grub-mkconfig -o /mnt/boot/grub/grub.cfg<br />
<br />
== Command Summary ==<br />
<br />
The following are all critical commands (exluded: the initial drive wipe which is optional). It assumes you have successfully brought up networking prior to starting this sequence.<br />
<br />
{{bc|<nowiki><br />
<br />
$DRIVE=/dev/DRIVEID<br />
<br />
sgdisk --zap-all $DRIVE<br />
<br />
sgdisk --clear \<br />
--new=1:0:+550MiB --typecode=1:ef00 --change-name=1:EFI \<br />
--new=2:0:+8GiB --typecode=2:8200 --change-name=2:cryptswap \<br />
--new=3:0:0 --typecode=2:8200 --change-name=3:cryptsystem \<br />
$DRIVE<br />
<br />
mksf.fat -F32 -n EFI /dev/disk/by-partlabel/EFI<br />
<br />
cryptsetup luksFormat --align-payload=8192 -s 256 -c aes-xts-plain64 /dev/disk/by-partlabel/cryptsystem<br />
<br />
cryptsetup open /dev/disk/by-partlabel/cryptsystem system<br />
<br />
cryptsetup open --type plain --key-file /dev/urandom /dev/disk/by-partlabel/cryptswap swap<br />
<br />
mkswap -L swap /dev/mapper/swap<br />
<br />
swapon -L swap<br />
<br />
mkfs.btrfs --force --label system /dev/mapper/system<br />
<br />
o=defaults,x-mount.mkdir<br />
<br />
o_btrfs=$o,compress=lzo,ssd,noatime<br />
<br />
mount -t btrfs LABEL=system /mnt<br />
<br />
btrfs subvolume create /mnt/root<br />
<br />
btrfs subvolume create /mnt/home<br />
<br />
btrfs subvolume create /mnt/snapshots<br />
<br />
umount -R /mnt<br />
<br />
mount -t btrfs -o subvol=root,$o_btrfs LABEL=system /mnt<br />
<br />
mount -t btrfs -o subvol=home,$o_btrfs LABEL=system /mnt/home<br />
<br />
mount -t btrfs -o subvol=snapshots,$o_btrfs LABEL=system /mnt/.snapshots<br />
<br />
pacstrap /mnt base<br />
<br />
genfstab -L -p /mnt >> /mnt/etc/fstab<br />
<br />
sed -i "s+LABEL=swap+/dev/mapper/swap" /etc/fstab_labels<br />
<br />
systemd-nspawn -bD /mnt<br />
<br />
echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen<br />
<br />
locale-gen<br />
<br />
localectl set-locale LANG=en_US.UTF-8<br />
<br />
timedatectl set-ntp 1<br />
<br />
timedatectl set-timezone America/Los_Angeles<br />
<br />
hostnamectl set-hostname myhostname<br />
<br />
echo "127.0.1.1 myhostname.localdomain myhostname" >> /etc/hosts<br />
<br />
pacman -Syu base-devel btrfs-progs iw gptfdisk zsh vim terminus-font<br />
</nowiki>}}<br />
<br />
== Extra: Sample "quick and dirty" Arch install using systemd-nspawn ==<br />
<br />
This is the approximate process I follow if I want to bring up Arch on, say, an old laptop for a quick purpose built test machine, etc. It's not an install that I consider long term maintainable since rollbacks aren't implemented, nor is there any encryption, but it's a good example of how simple installation can be.<br />
<br />
{{bc|<nowiki><br />
$DRIVE=/dev/DRIVEID<br />
sgdisk --zap-all $DRIVE<br />
mkfs.btrfs -f $DRIVE<br />
mount -t btrfs $DRIVE /mnt<br />
pacstrap /mnt base<br />
systemd-nspawn -bD /mnt<br />
echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen<br />
locale-gen<br />
localectl set-locale LANG=en_US.UTF-8<br />
timedatectl set-ntp 1<br />
timedatectl set-timezone America/Los_Angeles<br />
hostnamectl set-hostname myhostname<br />
poweroff<br />
grub-install --root-directory=/mnt $DRIVE<br />
grub-mkconfig -o /mnt/boot/grub/grub.cfg<br />
reboot<br />
</nowiki>}}</div>Altercationhttps://wiki.archlinux.org/index.php?title=User:Altercation/Bullet_Proof_Arch_Install&diff=458562User:Altercation/Bullet Proof Arch Install2016-12-05T22:46:28Z<p>Altercation: /* Bootloader */</p>
<hr />
<div>This page is a summary of the current process I follow when installing Arch on a new laptop or desktop. My process varies over time, but this serves as my "state of the art" best practice recommendations. I'm open to feedback and suggestions for improvements.<br />
<br />
{{Note|This is entirely based on my own opinions and research. It is opinionated about the best way to do things given the current state of the kernel, hardware availability, and utilities, filesystems, etc. I will explain my rationale for specific choices and provide links to other sources of information (on the Arch wiki or external) where useful.}}<br />
<br />
== Objectives ==<br />
<br />
The goals of my standard "bullet proof" Arch Linux installation are:<br />
<br />
* Benefit from Arch's rolling release model while mitigating any risk of system corruption or data loss due to failed upgrades<br />
* Minimize risk due to hardware failure or total system loss (e.g. theft or physical destruction)<br />
* Make system rollbacks easy and procedural, using a standard setup and methodology for recovery of previous system (and user data) states<br />
<br />
=== Why not the Arch Install instructions? ===<br />
<br />
The [[Installation guide|Arch Linux installation instructions]] are an excellent, general starting point and you should read and understand them. That being said, they are designed to map to a very, very broad set of installation scenarios. I am interested in a very specific type of installation (daily use desktops and laptops in this article) and I have a strong set of opinions about the "right" or "best practice" way to set up my own working systems.<br />
<br />
These instructions, then, are much more prescriptive and have strong suggestions or directions about how (and why) one should use a particular method during Arch Linux installation.<br />
<br />
=== Key differences from the stock Arch install instructions ===<br />
<br />
How these instructions differ from the standard Arch guidance:<br />
<br />
* We are encrypting the entire system but not using LVM as is often recommended (see the encryption section below for details about why we are not using it).<br />
* I use labels and avoid UUIDs where possible to make switching to an alternate recovery drive easier.<br />
* I skip arch-chroot and simply boot the new system ('''not''' reboot, just boot) from within the install environment using {{Man|1|systemd-nspawn}} which enables the *ctl commands to work (and systemd services to be enabled properly without need for a system reboot)<br />
* I use the various systemd *ctl commands (hostnamectl, timedatectl, localectl, etc.) to configure the system<br />
* I use the systemd mkinitcpio hooks in lieu of the legacy hooks.<br />
* I use BTRFS exclusively for root and home partitions for its backup capabilities.<br />
* I recommend and use secure boot (but not with the Microsoft keys) to minimize risk due to the unavoidably unencrypted EFI partition.<br />
<br />
== Assumptions ==<br />
<br />
These instructions presuppose the following:<br />
<br />
* fairly new hardware (these instructions may work on older hardware, but there may be unusual issues that crop up... if you aren't comfortable handling those situations you should consider a more "traditional" Arch Linux install (e.g. using grub, LVM, ext4, etc.)<br />
* [[Unified Extensible Firmware Interface|UEFI support]] (BIOS system install is also possible with some modification of these instructions, but this has not yet been detailed here)<br />
* probably an [[Solid State Drives|SSD]].<br />
* some familiarity with Arch, or at least some experience with Linux, will help<br />
<br />
{{Warning|I am assuming you are going to single boot (not dual boot) and that you are '''willing to wipe all data from the install drive.''' If that is not the case, do not proceed with these instructions as following them '''will effectively destroy any data (and other operating systems) on the installation target drive.'''}}<br />
<br />
== Prerequisites ==<br />
<br />
You must have a recent copy of the Arch install USB. See [[:Category:Getting and installing Arch]] for general information and [[USB flash installation media]] for specific details on creating a USB Arch installation drive.<br />
<br />
You should also have a reasonable amount of time in which to complete the installation. Novice users will want to budget a couple hours. Experienced users will ''know'' to budget a couple hours.<br />
<br />
== Preparation ==<br />
<br />
=== Boot from USB Drive ===<br />
<br />
Boot your system from your prepared [[USB flash installation media|Arch Linux USB drive]]. It is important that you boot in EFI mode, not legacy BIOS compatibility mode. See the [[Unified Extensible Firmware Interface|UEFI]] article for more information about checking boot mode and ensuring you are booting using EFI.<br />
<br />
=== Bring up the network ===<br />
<br />
If you booted into a system with an ethernet cable plugged in, chances are you're up and running. If you need to use wireless instead, {{ic|wifi-menu}} will more often than not work without trouble. If those don't work, see [[Installation guide#Connect to the Internet|the Arch installation guide section on connecting to the internet]].<br />
<br />
=== Select Drive ===<br />
<br />
I like to use the [[Core utilities#lsblk|{{ic|1=lsblk}}]] command to bring up a quick list of the block devices on the system and identify existing partition structures and sizes, as well as mount points. If you don't already use it, I recommend [[Core utilities#lsblk|{{ic|1=lsblk}}]] when you need information on any given drive or partition. It's useful for polling UUIDs as well. For example, the following command gives you a clearly formatted summary of all block devices, their partition labels, filesystem lables, UUIDs and partition UUIDS: {{ic|lsblk -o +LABEL,PARTLABEL,UUID,PARTUUID}}<br />
<br />
In any case, the plain command without options should be enough to identify the drive you will install to (for example {{ic|1=/dev/sda}} or {{ic|1=/dev/nvme0n1}}:<br />
<br />
# lsblk<br />
<br />
=== Wipe Drive Securely (optional) ===<br />
<br />
While it is not necessary, given that this process will go through the trouble of encrypting the main system partition, it makes sense to do a secure wipe of the drive. This is more or less directly from [[Dm-crypt/Drive preparation#dm-crypt wipe on an empty disk or partition]].<br />
<br />
{{Warning|Be certain of your target device selection as we will be '''wiping this drive''' (either securely or, at minimum, destroying all existing partition data).}}<br />
<br />
First, create a temporary encrypted container the full disk ({{ic|sdX}}) to be encrypted, e.g. using default encryption parameters and a random key via the {{ic|--key-file /dev/{u}random}} option (see also [[Random number generation]]):<br />
<br />
# cryptsetup open --type plain /dev/sdXY container --key-file /dev/urandom<br />
<br />
{{Note|An interesting page addressing myths about /dev/urandom can be [http://www.2uo.de/myths-about-urandom/ found here]}}<br />
<br />
Second, check the container exists:<br />
<br />
{{hc|# fdisk -l|Disk /dev/mapper/container: XXXX MB, XXXXXXXXXX bytes<br />
...<br />
Disk /dev/mapper/container does not contain a valid partition table}}<br />
Wipe the container with zeros. A use of {{ic|1=if=/dev/urandom}} is '''not''' required as the encryption cipher itself generates randomness.<br />
{{hc|# dd <nowiki>if=/dev/zero of=/dev/mapper/container status=progress bs=1M</nowiki>|<br />
dd: writing to ‘/dev/mapper/container’: No space left on device}}<br />
<br />
{{Tip|<br />
* Using ''dd'' with the {{ic|1=bs=}} option, e.g. {{ic|1=bs=1M}} as above, is frequently used to increase disk throughput of the operation.<br />
* To perform a check of the operation, zero the partition before creating the wipe container. After the wipe command {{ic|blockdev --getsize64 ''/dev/mapper/container''}} can be used to get the exact container size as root. Now ''od'' can be used to spotcheck whether the wipe overwrote the zeroed sectors, e.g. {{ic|od -j ''containersize - blocksize''}} to view the wipe completed to the end.}}<br />
<br />
Finally, close the temporary container:<br />
<br />
# cryptsetup close container<br />
<br />
== Partition & Format Drive ==<br />
<br />
=== Understanding some basics about disks, partitions, and filesystems ===<br />
<br />
Think of your drive like a big empty building, no rooms. This is your plain physical drive (either a spinning platter drive or an SSD). Next imagine that to make it useful, we divide the building into apartments. In our analogy the apartments are '''partitions''' of the drive.<br />
<br />
Imagine also that there are a couple different standard methods of creating layout maps to the apartments. These plans are standardized so that the public services that have to access the building regularly (like the fire and police, for example) understand how to find the apartment entrances. In the world of partitioning, the equivalent is the "partition table scheme". The two common schemes are called "MBR" (Master Boot Record, older) and "GPT" (GUID Partition Table, newer). We will be using the new GPT scheme.<br />
<br />
Finally, imagine that the apartments are just empty shells. The act of building walls and laying out the functional structure of the apartments is equivalent to formatting our disk partitions with a filesystem. And just as different layouts may be more or less efficient, or have other different functional characteristics, so to filesystems have different attributes that make them useful in different ways.<br />
<br />
=== Our partition plans ===<br />
<br />
We will take our physical drive and divide it into three partitions. These partitions each serve a distinct purpose. All but the first and smallest, the EFI partition, will be encrypted. For security, if your system supports Secure Boot, you may choose to cryptographically sign the data stored on the EFI partition so that any tampering will be evident, despite the lack of encryption on that partition.<br />
<br />
{{Note|Again, we're assuming an UEFI installation (not legacy BIOS) and a GPT (not MBR) partition structure. If none of that made sense, best to start with the [[Partitioning]] article or do some test installs of Arch first. '''Partitioning is, in my opinion, one of the areas that is most confusing for the new Arch user.''' Additionally, there is a lot "received wisdom" and cargo-cult assumption making about how best to partition. Working through some of the "this is how it's always been done" tutorials isn't necessarily a bad thing... In many cases the way it has always been done has some sound reasoning behind it, despite being cargo-culted half the time. That being said, the method presented here is different from that in most of the Arch wiki partitioning methodologies.}}<br />
<br />
We will not be using LVM. You read a lot about LUKS and LVM and it all gets a bit complicated (LVM on LUKS, LUKS on LVM, etc.). LVM is a "logical volume manager" and abstracts physical devices (drives) into virtual devices, for easier management. It's a good idea but we will be using btrfs to effectively achieve the same results and really don't need the overhead of LVM.<br />
<br />
=== Partition Summary ===<br />
<br />
* 1: EFI - The UEFI 'bios" will look for this FAT32 formatted partition and either locate a default bootloader or will locate a specific EFI boot entry on it. This partition is by necessity not encrypted (unless the drive it is on has been encrypted as a "self encrypting drive")<br />
* 2: Swap - Used by Linux to swap out pages of memory from RAM to disk. Despite debate in this area, it is advisable to have at least some swap space, even it you are not planning on using hibernation on your machine. The Arch wiki is unfortunately rather too brief in its own [[Swap|swap article]] so I recommend the [https://docs.fedoraproject.org/en-US/Fedora/14/html/Storage_Administration_Guide/ch-swapspace.html Fedora documentation on swap] for a good overview on determining the right swap partition size.<br />
* 3: System - This will hold our root and home data. It will be formatted as BTRFS and will use subvolumes to manage snapshots of the current root and home contents.<br />
<br />
=== Visual overview of our partitions, filesystems, and contents ===<br />
<br />
This is a visual summary of our partions (inc. size information), encryption, filesystems, and a summary of the contents of each container.<br />
<br />
{| class="wikitable"<br />
| style="vertical-align: top; padding:1em" | '''Partition 1 (EFI)'''<br />
550MiB+<br />
{| style="border: 1px solid black; background: #DACEF2; margin: 1em;"<br />
! FAT32<br />
|-<br />
|kernel & initramfs<br />
(signed if using secure boot)<br />
|}<br />
| style="vertical-align: top; padding:1em" | '''Partition 2 (Swap)'''<br />
w/ Hibernate: Equal RAM,<br />
w/o Hibernate: min 8GB<br />
{| style="border: 1px solid black; background: #F2ECCE; margin: 1em;"<br />
|-<br />
! dm-crypt<br />
{| style="border: 1px solid black; background: #DACEF2; margin: 1em;"<br />
| SWAP<br />
|}<br />
|}<br />
| style="vertical-align: top; padding:1em" | '''Partition 3 (System)'''<br />
Remaining Space<br />
{| style="border: 1px solid black; background: #F2ECCE; margin: 1em;"<br />
|-<br />
! LUKS dm-crypt<br />
<br />
{| style="border: 1px solid black; background: #DACEF2; margin: 1em;"<br />
| BTRFS Top Level Subvolume<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Root Subvolume<br />
|}<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Home Subvolume<br />
|}<br />
<br />
{| style="border: 1px solid black; background: #E0CEF2; margin: 1em;"<br />
| BTRFS Snapshots Subvolume<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Root Snapshot Subvolume(s)<br />
|}<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Home Snapshot Subvolume(s)<br />
|}<br />
<br />
|}<br />
<br />
|}<br />
<br />
|}<br />
<br />
|}<br />
<br />
=== Partition Drive ===<br />
<br />
There are many utilities available for [[Partitioning]]. Because we are using Arch Linux and the command line doesn't hurt us (it makes us stronger) we will be using pure, non-interactive command line tools for this. Specifically, we will be using the utility [[Fdisk#Using_sgdisk|sgdisk]] from the {{Pkg|gptfdisk}} package. The [[Fdisk|fdisk]] utility now also supports GPT partitioned drives, so it would be an alternative. [[Fdisk#Using_sgdisk|sgdisk]] is available by default on the standard Arch install iso that you use to make your bootable USB drive.<br />
<br />
First, select the drive you will install to. Make sure you have selected the correct drive!. Again, a quick {{ic|lsblk}} will work here.<br />
<br />
# $DRIVE=/dev/DRIVEID<br />
<br />
(replace /dev/DRIVEID with the correct value, for example /dev/sda, /dev/nvme0n1, etc.)<br />
<br />
If you didn't securely wipe the drive already, it's worth "zapping" it using [[Fdisk#Using_sgdisk|sgdisk]] to remove any lingering legacy partition information. If you already wiped the drive you can skip this command (though it won't hurt to run it again).<br />
<br />
{{Warning|'''This command will also effectively erase the selected drive!'''}}<br />
<br />
# sgdisk --zap-all $DRIVE<br />
<br />
The following command will then create all three partitions in one go. '''It will also effectively erase the selected drive!'''<br />
<br />
# sgdisk --clear \<br />
--new=1:0:+550MiB --typecode=1:ef00 --change-name=1:EFI \<br />
--new=2:0:+8GiB --typecode=2:8200 --change-name=2:cryptswap \<br />
--new=3:0:0 --typecode=2:8200 --change-name=3:cryptsystem \<br />
$DRIVE<br />
<br />
It is worth noting that the "--change-name" values are, in this case, creating GPT "partition labels". You can subsequently see these by using the {{ic|lsblk -o +PARTLABEL}} command. It is good to use "EFI" for the efi partition. I am not aware of UEFI implementations that actively use the label for identification of the EFI partition, but it is possible that some do (UEFI bios implementations are not always consistent or to spec). The other two names are entirely "arbitrary". There is nothing special about calling them cryptswap and cryptsystem; they are simply good, clear names that remind us of the purpose of this partition and what it contains (for example, "cryptswap" suggests "this partition is for swap, and is encrypted").<br />
<br />
One final note about partition labels: we want them to be unique on your system. If for some reason there is already a GPT partition with the name EFI on another drive on your system, either change that partition name or use something besides "EFI" to avoid a namespace collision.<br />
<br />
Note also, that the backslashes at the end of each line can be omitted if you are writing the command on one long line instead. Those simply allow the splitting of a single command onto multiple lines.<br />
<br />
=== Format EFI Partition ===<br />
<br />
Next up: format the first (EFI) partition using the (required) FAT32 filesystem.<br />
<br />
# mksf.fat -F32 -n EFI /dev/disk/by-partlabel/EFI<br />
<br />
Note that we here make use of the partition label we just assigned. I prefer doing this since it simplifies scripts significantly for me and makes them, in my opinion, more readable.<br />
<br />
=== Encrypt System Partition ===<br />
<br />
Encrypt the main partition. Use a good passphrase. Note that the "--align-payload" value has been used as per [http://www.spinics.net/lists/dm-crypt/msg02421.html this suggestion/explanation] on the dm-crypt mailing list.<br />
<br />
Note also that I selected the encryption algorithm and key size using cryptsetup benchmark. See the [[Dm-crypt/Device_encryption]] article for more details.<br />
<br />
# cryptsetup luksFormat --align-payload=8192 -s 256 -c aes-xts-plain64 /dev/disk/by-partlabel/cryptsystem<br />
<br />
After creating the encrypted container, open it. Again, note the use of the partition label to identify the drive. Additionally, note that once we open this device we are giving it a name of "system." Thus "cryptsystem" is the encrypted system partition, while "system" is the name we are using once it has been opened in an unencrypted state. These names are arbitrary (Linux doesn't care what we use) but they help us keep things organized during this process.<br />
<br />
# cryptsetup open /dev/disk/by-partlabel/cryptsystem system<br />
<br />
=== Bring Up Encrypted Swap ===<br />
<br />
Finally we create encrypted swap. In this example we are not enabling hibernation. I will provide information on how to enable hibernation separately. Again, using partition labels to identify the partition and going from "cryptswap" to just "swap".<br />
<br />
We are not using LUKS here (which effectively makes dm-crypt easier to use). We're just using plain dm-crypt to encrypt the swap partition using a random key.<br />
<br />
# cryptsetup open --type plain --key-file /dev/urandom /dev/disk/by-partlabel/cryptswap swap<br />
# mkswap -L swap /dev/mapper/swap<br />
# swapon -L swap<br />
<br />
=== Create BTRFS Subvolumes ===<br />
<br />
Now on to the main attraction: creating our BTRFS subvolume structure. While BTRFS can be set up like any other filesystem (single command, just use the created file system directly), we're going to use the power of BTRFS to enable snapshotting our system state efficiently and rollbacks as necessary.<br />
<br />
First we create a top-level BTRFS subvolume. Note that the top-level entity in BTRFS nomenclature is still referred to as a '''sub'''volume, despite being at the top-level.<br />
<br />
We will create and mount this subvolume, create some new subvolumes inside it, and then switch to those subvolumes as our proper, mounted filesystems. Doing this will enable us to treat our root filesystem as a snapshotable object.<br />
<br />
Top-level subvolume creation.<br />
<br />
# mkfs.btrfs --force --label system /dev/mapper/system<br />
<br />
Temporarily mount our top-level volume for further subvolume creation. Note that the variable 'o' in this case is our default set of options for any given filesystem mount, while "o_btrfs" are those plus some options specific to btrfs. The default option "x-mount.mkdir" is a neat trick that allows us to skip the creation of directories for mountpoints (they will be created automatically). We assume /mnt as the standard mount point, as in a normal Arch Linux installation.<br />
<br />
# o=defaults,x-mount.mkdir<br />
# o_btrfs=$o,compress=lzo,ssd,noatime<br />
<br />
Note the use of our filesystem label to mount our subvolume. This is distinct from the partition labels used earlier. See the Arch wiki article on [[Persistent_block_device_naming]] for more information.<br />
<br />
# mount -t btrfs LABEL=system /mnt<br />
<br />
Now we create the subvolumes which will actually be mounted in our running system:<br />
<br />
# btrfs subvolume create /mnt/root<br />
# btrfs subvolume create /mnt/home<br />
# btrfs subvolume create /mnt/snapshots<br />
<br />
Then we unmount everything...<br />
<br />
# umount -R /mnt<br />
<br />
And remount just the subvolumes under our top-level subvolume (which remains unmounted unless we need to do "surgery" and rollback to a previous system system):<br />
<br />
# mount -t btrfs -o subvol=root,$o_btrfs LABEL=system /mnt<br />
<br />
Before mounting the home and snapshots subvolumes, let's walk through that command so we understand what it's doing:<br />
<br />
The 'mount -t btrfs' just specifies that our filesystem is of type BTRFS. This is often not necessary since mount will attempt to identify the filesystem type, but being explicit is often the best strategy with command line utilities, so we identify the type here.<br />
<br />
We use our previously defined mount options with the $o_btrfs variable and add the additional option "subvol=root" (separating it from our other defaults with a comma, of course). The next part of the command is "LABEL=system". Combined this reads as "mount the filesystem with the 'system' label, and use the 'root' subvolume within that".<br />
<br />
Finally, all this gets mounted at our install root, which in this case is "/mnt".<br />
<br />
Now let's pick back up and mount our home and snapshots subvolumes. Note that while the subvolume name is "snapshots", we will mount it at ".snapshots" (note dot prefix for the mount point). This will keep our root directory listing clean but will still make it available at a reasonable mount location.<br />
<br />
# mount -t btrfs -o subvol=home,$o_btrfs LABEL=system /mnt/home<br />
# mount -t btrfs -o subvol=snapshots,$o_btrfs LABEL=system /mnt/.snapshots<br />
<br />
It it worth noting that in each case we are telling mount to use the same filesystem, namely the one labeled "system". However in each case we are also telling it to look for a different subvolume in that filesystem (via the "subvol=" option).<br />
<br />
With this done, we can move on to installing the actual system.<br />
<br />
== Installation of Base Arch Linux System ==<br />
<br />
We are currently running off the Arch installer root filesystem. We will first use the 'pacstrap' utility to start our installation and then we will boot into our new minimal system using systemd-nspawn.<br />
<br />
=== Install base package group ===<br />
<br />
# pacstrap /mnt base<br />
<br />
=== fstab Generation and Modification ===<br />
<br />
{{Note|In a simpler, non encrypted configuration it is possible to skip making an fstab altogether due to a standard known as the [https://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/ Discoverable Partitions Spec]. However given the complexity of our encrypted, btrfs subvolume configuration, we require an fstab at this time. It is possible that in future we might feasibly do away with the fstab almost entirely in this setup (see the [https://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/#whataboutautomaticmountingofbtrfssubvolumestovarhomeandsoon 'What about automatic mounting of btrfs subvolumes'] section on that page).}}<br />
<br />
Create an [[fstab]] filesystem table file, using labels (-L) to identify the filesystems.<br />
<br />
# genfstab -L -p /mnt >> /mnt/etc/fstab<br />
<br />
I prefer to use labels as this makes the system more portable to a backup drive. You should end up with something that looks pretty close to this:<br />
<br />
{{hc|# cat /mnt/etc/fstab|<nowiki><br />
# /dev/mapper/system UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=system / btrfs rw,noatime,compress=lzo,ssd,space_cache,subvolid=257,subvol=/root,subvol=root 0 0<br />
<br />
# /dev/mapper/system UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=system /home btrfs rw,noatime,compress=lzo,ssd,space_cache,subvolid=258,subvol=/home,subvol=home 0 0<br />
<br />
# /dev/mapper/system UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=system /.snapshots btrfs rw,noatime,compress=lzo,ssd,space_cache,subvolid=259,subvol=/snapshots,subvol=snapshots 0 0<br />
<br />
# /dev/nvme0n1p1 UUID=xxxx-xxxx<br />
LABEL=EFI /boot/EFI vfat rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro 0 2<br />
<br />
# /dev/mapper/swap UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=swap none swap defaults 0 0<br />
</nowiki>}}<br />
<br />
There is one problem, however. Swap will not remount this way (the plain dm-crypt partition with a random key will not have a label when it is recreated on reboot). You will have to change that line from this:<br />
<br />
{{bc|<nowiki>LABEL=swap none swap defaults 0 0</nowiki>}}<br />
<br />
to this:<br />
<br />
{{bc|/dev/mapper/swap none swap defaults 0 0}}<br />
<br />
This will ensure that the mapped device is opened as swap successfully. The other lines may remain unchanged.<br />
<br />
==== Use {{ic|sed}} instead ====<br />
<br />
As a (scriptable) alternative to the manual editing of your {{ic|/etc/fstab}} you could use {{Man|1|sed}} to edit the file in place:<br />
<br />
# sed -i "s+LABEL=swap+/dev/mapper/swap" /etc/fstab_labels<br />
<br />
=== Boot into new system ===<br />
<br />
# systemd-nspawn -bD /mnt<br />
<br />
This will boot your new base Arch Linux system. After the standard boot messages scroll by you will be presented with a login (enter {{ic|root}} and hit enter to login).<br />
<br />
=== Generate and set locale ===<br />
<br />
Next, edit and uncomment your desired locale(s) from {{ic|/etc/locale.gen}}. We use {{ic|vi}} in the example below, but you could use a simpler editor such as {{ic|nano}} if you wish.<br />
<br />
{{hc|vi /etc/locale.gen|<nowiki><br />
...<br />
#en_PH.UTF-8 UTF-8<br />
#en_PH ISO-8859-1<br />
#en_SG.UTF-8 UTF-8<br />
#en_SG ISO-8859-1<br />
#en_US.UTF-8 UTF-8<br />
#en_US ISO-8859-1<br />
#en_ZA.UTF-8 UTF-8<br />
#en_ZA ISO-8859-1<br />
#en_ZM UTF-8<br />
...<br />
</nowiki>}}<br />
<br />
Changing it to (for en_US.UTF-8 as a locale in this example):<br />
<br />
{{bc|<nowiki><br />
...<br />
#en_PH.UTF-8 UTF-8<br />
#en_PH ISO-8859-1<br />
#en_SG.UTF-8 UTF-8<br />
#en_SG ISO-8859-1<br />
en_US.UTF-8 UTF-8<br />
#en_US ISO-8859-1<br />
#en_ZA.UTF-8 UTF-8<br />
#en_ZA ISO-8859-1<br />
#en_ZM UTF-8<br />
...<br />
</nowiki>}}<br />
<br />
Alternately one could simply append a known value to the {{ic|/etc/locale.gen}} file:<br />
<br />
# echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen<br />
<br />
After either method, one runs the {{ic|locale-gen}} command to generate the locale files:<br />
<br />
# locale-gen<br />
<br />
Finally we use {{Man|1|systemd-firstboot}} or {{Man|1|localectl}} to set the system locale. Each of these effectively does the same thing which is to simply write to {{ic|/etc/locale.conf}} (which can simply be edited directly as per standard Arch install instructions).<br />
<br />
==== With systemd-firstboot ====<br />
<br />
{{Man|1|systemd-firstboot}} will prompt us for selection from our generated locales. It will only work if there is no assigned system locale. If you wish to make changes afterward you can use {{Man|1|localectl}}<br />
<br />
# systemd-firstboot --prompt-locale<br />
<br />
==== With localectl ====<br />
<br />
This is an alternate to using {{ic|systemd-firstboot --prompt-locale}}. It may also be used subsequent to that command if further changes to the locale are desired.<br />
<br />
If you need a reminder of which locales have been installed (during this install or later during system changes), use {{ic|localectl list-locales}}:<br />
<br />
{{hc|<nowiki># localectl list-locales</nowiki>|en_US.UTF-8}}<br />
<br />
We then use {{ic|localectl set-locale}}:<br />
<br />
# localectl set-locale LANG=en_US.UTF-8<br />
<br />
=== Time and Date ===<br />
<br />
Unless you have a reason not to, we'll turn on NTP synchronization.<br />
<br />
# timedatectl set-ntp 1<br />
<br />
Then list timezones and pick one<br />
<br />
{{hc|<nowiki># timedatectl list-timezones</nowiki>|<nowiki><br />
...<br />
America/Kentucky/Louisville<br />
America/Kentucky/Monticello<br />
America/Kralendijk<br />
America/La_Paz<br />
America/Lima<br />
America/Los_Angeles<br />
America/Lower_Princes<br />
America/Maceio<br />
America/Managua<br />
America/Manaus<br />
America/Marigot<br />
America/Martinique<br />
America/Matamoros<br />
...<br />
</nowiki>}}<br />
# timedatectl set-timezone America/Los_Angeles<br />
<br />
=== Set hostname ===<br />
<br />
# hostnamectl set-hostname myhostname<br />
<br />
See the man page for {{Man|1|hostnamectl}} for other attributes that can be set. You might also add the hostname to {{Man|5|hosts}}:<br />
<br />
{{hc|/etc/hosts|<br />
127.0.0.1 localhost.localdomain localhost<br />
::1 localhost.localdomain localhost<br />
'''127.0.1.1 ''myhostname''.localdomain ''myhostname'''''<br />
}}<br />
<br />
Use {{ic|echo}} for a scriptable solution:<br />
<br />
# echo "127.0.1.1 myhostname.localdomain myhostname" >> /etc/hosts<br />
<br />
=== Network configuration ===<br />
<br />
Configure the network for the newly installed environment: see [[Network configuration]].<br />
<br />
For [[Wireless configuration]], [[Help:Reading#Installation of packages|install]] the {{Pkg|iw}}, {{Pkg|wpa_supplicant}}, and {{Pkg|dialog}} packages, as well as needed [[Wireless#Installing driver/firmware|firmware packages]].<br />
<br />
=== Base Package Installation ===<br />
<br />
We've already included the {{Grp|base}} group which is, strictly speaking, all you need to boot a minimal Arch Linux system. At this stage, however, we can install some useful utilities (and Xorg or Wayland, etc.).<br />
<br />
# pacman -Syu base-devel btrfs-progs iw gptfdisk zsh vim terminus-font<br />
<br />
=== Initramfs ===<br />
<br />
Creating a new ''initramfs'' is usually not required, because [[mkinitcpio]] was run on installation of the {{Pkg|linux}} package with ''pacstrap''.<br />
<br />
For special configurations, modify the {{man|5|mkinitcpio.conf|url=}} file and recreate the initramfs image:<br />
<br />
# mkinitcpio -p linux<br />
<br />
=== Bootloader ===<br />
<br />
{{Warning|THIS SECTION IN PROGRESS}}<br />
<br />
=== Root password ===<br />
<br />
Set the root [[password]]:<br />
<br />
# passwd<br />
<br />
=== Leave the systemd-nspawn environment ===<br />
<br />
Issue a poweroff to exit the nspawned environment:<br />
<br />
# poweroff<br />
<br />
This will return you the Arch installer environment where you can wrap up.<br />
<br />
=== Legacy boot loader ===<br />
<br />
If your system is not UEFI and you need to use a legacy installer like grub, it will need to be installed from the Arch installer environment, not the systemd-nspawn fresh install. An example of this would be (assuming that the drive of the new system is at /dev/sdb):<br />
<br />
# grub-install --root-directory=/mnt /dev/sdb<br />
# grub-mkconfig -o /mnt/boot/grub/grub.cfg<br />
<br />
== Command Summary ==<br />
<br />
The following are all critical commands (exluded: the initial drive wipe which is optional). It assumes you have successfully brought up networking prior to starting this sequence.<br />
<br />
{{bc|<nowiki><br />
<br />
$DRIVE=/dev/DRIVEID<br />
<br />
sgdisk --zap-all $DRIVE<br />
<br />
sgdisk --clear \<br />
--new=1:0:+550MiB --typecode=1:ef00 --change-name=1:EFI \<br />
--new=2:0:+8GiB --typecode=2:8200 --change-name=2:cryptswap \<br />
--new=3:0:0 --typecode=2:8200 --change-name=3:cryptsystem \<br />
$DRIVE<br />
<br />
mksf.fat -F32 -n EFI /dev/disk/by-partlabel/EFI<br />
<br />
cryptsetup luksFormat --align-payload=8192 -s 256 -c aes-xts-plain64 /dev/disk/by-partlabel/cryptsystem<br />
<br />
cryptsetup open /dev/disk/by-partlabel/cryptsystem system<br />
<br />
cryptsetup open --type plain --key-file /dev/urandom /dev/disk/by-partlabel/cryptswap swap<br />
<br />
mkswap -L swap /dev/mapper/swap<br />
<br />
swapon -L swap<br />
<br />
mkfs.btrfs --force --label system /dev/mapper/system<br />
<br />
o=defaults,x-mount.mkdir<br />
<br />
o_btrfs=$o,compress=lzo,ssd,noatime<br />
<br />
mount -t btrfs LABEL=system /mnt<br />
<br />
btrfs subvolume create /mnt/root<br />
<br />
btrfs subvolume create /mnt/home<br />
<br />
btrfs subvolume create /mnt/snapshots<br />
<br />
umount -R /mnt<br />
<br />
mount -t btrfs -o subvol=root,$o_btrfs LABEL=system /mnt<br />
<br />
mount -t btrfs -o subvol=home,$o_btrfs LABEL=system /mnt/home<br />
<br />
mount -t btrfs -o subvol=snapshots,$o_btrfs LABEL=system /mnt/.snapshots<br />
<br />
pacstrap /mnt base<br />
<br />
genfstab -L -p /mnt >> /mnt/etc/fstab<br />
<br />
sed -i "s+LABEL=swap+/dev/mapper/swap" /etc/fstab_labels<br />
<br />
systemd-nspawn -bD /mnt<br />
<br />
echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen<br />
<br />
locale-gen<br />
<br />
localectl set-locale LANG=en_US.UTF-8<br />
<br />
timedatectl set-ntp 1<br />
<br />
timedatectl set-timezone America/Los_Angeles<br />
<br />
hostnamectl set-hostname myhostname<br />
<br />
echo "127.0.1.1 myhostname.localdomain myhostname" >> /etc/hosts<br />
<br />
pacman -Syu base-devel btrfs-progs iw gptfdisk zsh vim terminus-font<br />
</nowiki>}}</div>Altercationhttps://wiki.archlinux.org/index.php?title=User:Altercation/Bullet_Proof_Arch_Install&diff=458561User:Altercation/Bullet Proof Arch Install2016-12-05T22:14:31Z<p>Altercation: /* Command Summary */</p>
<hr />
<div>This page is a summary of the current process I follow when installing Arch on a new laptop or desktop. My process varies over time, but this serves as my "state of the art" best practice recommendations. I'm open to feedback and suggestions for improvements.<br />
<br />
{{Note|This is entirely based on my own opinions and research. It is opinionated about the best way to do things given the current state of the kernel, hardware availability, and utilities, filesystems, etc. I will explain my rationale for specific choices and provide links to other sources of information (on the Arch wiki or external) where useful.}}<br />
<br />
== Objectives ==<br />
<br />
The goals of my standard "bullet proof" Arch Linux installation are:<br />
<br />
* Benefit from Arch's rolling release model while mitigating any risk of system corruption or data loss due to failed upgrades<br />
* Minimize risk due to hardware failure or total system loss (e.g. theft or physical destruction)<br />
* Make system rollbacks easy and procedural, using a standard setup and methodology for recovery of previous system (and user data) states<br />
<br />
=== Why not the Arch Install instructions? ===<br />
<br />
The [[Installation guide|Arch Linux installation instructions]] are an excellent, general starting point and you should read and understand them. That being said, they are designed to map to a very, very broad set of installation scenarios. I am interested in a very specific type of installation (daily use desktops and laptops in this article) and I have a strong set of opinions about the "right" or "best practice" way to set up my own working systems.<br />
<br />
These instructions, then, are much more prescriptive and have strong suggestions or directions about how (and why) one should use a particular method during Arch Linux installation.<br />
<br />
=== Key differences from the stock Arch install instructions ===<br />
<br />
How these instructions differ from the standard Arch guidance:<br />
<br />
* We are encrypting the entire system but not using LVM as is often recommended (see the encryption section below for details about why we are not using it).<br />
* I use labels and avoid UUIDs where possible to make switching to an alternate recovery drive easier.<br />
* I skip arch-chroot and simply boot the new system ('''not''' reboot, just boot) from within the install environment using {{Man|1|systemd-nspawn}} which enables the *ctl commands to work (and systemd services to be enabled properly without need for a system reboot)<br />
* I use the various systemd *ctl commands (hostnamectl, timedatectl, localectl, etc.) to configure the system<br />
* I use the systemd mkinitcpio hooks in lieu of the legacy hooks.<br />
* I use BTRFS exclusively for root and home partitions for its backup capabilities.<br />
* I recommend and use secure boot (but not with the Microsoft keys) to minimize risk due to the unavoidably unencrypted EFI partition.<br />
<br />
== Assumptions ==<br />
<br />
These instructions presuppose the following:<br />
<br />
* fairly new hardware (these instructions may work on older hardware, but there may be unusual issues that crop up... if you aren't comfortable handling those situations you should consider a more "traditional" Arch Linux install (e.g. using grub, LVM, ext4, etc.)<br />
* [[Unified Extensible Firmware Interface|UEFI support]] (BIOS system install is also possible with some modification of these instructions, but this has not yet been detailed here)<br />
* probably an [[Solid State Drives|SSD]].<br />
* some familiarity with Arch, or at least some experience with Linux, will help<br />
<br />
{{Warning|I am assuming you are going to single boot (not dual boot) and that you are '''willing to wipe all data from the install drive.''' If that is not the case, do not proceed with these instructions as following them '''will effectively destroy any data (and other operating systems) on the installation target drive.'''}}<br />
<br />
== Prerequisites ==<br />
<br />
You must have a recent copy of the Arch install USB. See [[:Category:Getting and installing Arch]] for general information and [[USB flash installation media]] for specific details on creating a USB Arch installation drive.<br />
<br />
You should also have a reasonable amount of time in which to complete the installation. Novice users will want to budget a couple hours. Experienced users will ''know'' to budget a couple hours.<br />
<br />
== Preparation ==<br />
<br />
=== Boot from USB Drive ===<br />
<br />
Boot your system from your prepared [[USB flash installation media|Arch Linux USB drive]]. It is important that you boot in EFI mode, not legacy BIOS compatibility mode. See the [[Unified Extensible Firmware Interface|UEFI]] article for more information about checking boot mode and ensuring you are booting using EFI.<br />
<br />
=== Bring up the network ===<br />
<br />
If you booted into a system with an ethernet cable plugged in, chances are you're up and running. If you need to use wireless instead, {{ic|wifi-menu}} will more often than not work without trouble. If those don't work, see [[Installation guide#Connect to the Internet|the Arch installation guide section on connecting to the internet]].<br />
<br />
=== Select Drive ===<br />
<br />
I like to use the [[Core utilities#lsblk|{{ic|1=lsblk}}]] command to bring up a quick list of the block devices on the system and identify existing partition structures and sizes, as well as mount points. If you don't already use it, I recommend [[Core utilities#lsblk|{{ic|1=lsblk}}]] when you need information on any given drive or partition. It's useful for polling UUIDs as well. For example, the following command gives you a clearly formatted summary of all block devices, their partition labels, filesystem lables, UUIDs and partition UUIDS: {{ic|lsblk -o +LABEL,PARTLABEL,UUID,PARTUUID}}<br />
<br />
In any case, the plain command without options should be enough to identify the drive you will install to (for example {{ic|1=/dev/sda}} or {{ic|1=/dev/nvme0n1}}:<br />
<br />
# lsblk<br />
<br />
=== Wipe Drive Securely (optional) ===<br />
<br />
While it is not necessary, given that this process will go through the trouble of encrypting the main system partition, it makes sense to do a secure wipe of the drive. This is more or less directly from [[Dm-crypt/Drive preparation#dm-crypt wipe on an empty disk or partition]].<br />
<br />
{{Warning|Be certain of your target device selection as we will be '''wiping this drive''' (either securely or, at minimum, destroying all existing partition data).}}<br />
<br />
First, create a temporary encrypted container the full disk ({{ic|sdX}}) to be encrypted, e.g. using default encryption parameters and a random key via the {{ic|--key-file /dev/{u}random}} option (see also [[Random number generation]]):<br />
<br />
# cryptsetup open --type plain /dev/sdXY container --key-file /dev/urandom<br />
<br />
{{Note|An interesting page addressing myths about /dev/urandom can be [http://www.2uo.de/myths-about-urandom/ found here]}}<br />
<br />
Second, check the container exists:<br />
<br />
{{hc|# fdisk -l|Disk /dev/mapper/container: XXXX MB, XXXXXXXXXX bytes<br />
...<br />
Disk /dev/mapper/container does not contain a valid partition table}}<br />
Wipe the container with zeros. A use of {{ic|1=if=/dev/urandom}} is '''not''' required as the encryption cipher itself generates randomness.<br />
{{hc|# dd <nowiki>if=/dev/zero of=/dev/mapper/container status=progress bs=1M</nowiki>|<br />
dd: writing to ‘/dev/mapper/container’: No space left on device}}<br />
<br />
{{Tip|<br />
* Using ''dd'' with the {{ic|1=bs=}} option, e.g. {{ic|1=bs=1M}} as above, is frequently used to increase disk throughput of the operation.<br />
* To perform a check of the operation, zero the partition before creating the wipe container. After the wipe command {{ic|blockdev --getsize64 ''/dev/mapper/container''}} can be used to get the exact container size as root. Now ''od'' can be used to spotcheck whether the wipe overwrote the zeroed sectors, e.g. {{ic|od -j ''containersize - blocksize''}} to view the wipe completed to the end.}}<br />
<br />
Finally, close the temporary container:<br />
<br />
# cryptsetup close container<br />
<br />
== Partition & Format Drive ==<br />
<br />
=== Understanding some basics about disks, partitions, and filesystems ===<br />
<br />
Think of your drive like a big empty building, no rooms. This is your plain physical drive (either a spinning platter drive or an SSD). Next imagine that to make it useful, we divide the building into apartments. In our analogy the apartments are '''partitions''' of the drive.<br />
<br />
Imagine also that there are a couple different standard methods of creating layout maps to the apartments. These plans are standardized so that the public services that have to access the building regularly (like the fire and police, for example) understand how to find the apartment entrances. In the world of partitioning, the equivalent is the "partition table scheme". The two common schemes are called "MBR" (Master Boot Record, older) and "GPT" (GUID Partition Table, newer). We will be using the new GPT scheme.<br />
<br />
Finally, imagine that the apartments are just empty shells. The act of building walls and laying out the functional structure of the apartments is equivalent to formatting our disk partitions with a filesystem. And just as different layouts may be more or less efficient, or have other different functional characteristics, so to filesystems have different attributes that make them useful in different ways.<br />
<br />
=== Our partition plans ===<br />
<br />
We will take our physical drive and divide it into three partitions. These partitions each serve a distinct purpose. All but the first and smallest, the EFI partition, will be encrypted. For security, if your system supports Secure Boot, you may choose to cryptographically sign the data stored on the EFI partition so that any tampering will be evident, despite the lack of encryption on that partition.<br />
<br />
{{Note|Again, we're assuming an UEFI installation (not legacy BIOS) and a GPT (not MBR) partition structure. If none of that made sense, best to start with the [[Partitioning]] article or do some test installs of Arch first. '''Partitioning is, in my opinion, one of the areas that is most confusing for the new Arch user.''' Additionally, there is a lot "received wisdom" and cargo-cult assumption making about how best to partition. Working through some of the "this is how it's always been done" tutorials isn't necessarily a bad thing... In many cases the way it has always been done has some sound reasoning behind it, despite being cargo-culted half the time. That being said, the method presented here is different from that in most of the Arch wiki partitioning methodologies.}}<br />
<br />
We will not be using LVM. You read a lot about LUKS and LVM and it all gets a bit complicated (LVM on LUKS, LUKS on LVM, etc.). LVM is a "logical volume manager" and abstracts physical devices (drives) into virtual devices, for easier management. It's a good idea but we will be using btrfs to effectively achieve the same results and really don't need the overhead of LVM.<br />
<br />
=== Partition Summary ===<br />
<br />
* 1: EFI - The UEFI 'bios" will look for this FAT32 formatted partition and either locate a default bootloader or will locate a specific EFI boot entry on it. This partition is by necessity not encrypted (unless the drive it is on has been encrypted as a "self encrypting drive")<br />
* 2: Swap - Used by Linux to swap out pages of memory from RAM to disk. Despite debate in this area, it is advisable to have at least some swap space, even it you are not planning on using hibernation on your machine. The Arch wiki is unfortunately rather too brief in its own [[Swap|swap article]] so I recommend the [https://docs.fedoraproject.org/en-US/Fedora/14/html/Storage_Administration_Guide/ch-swapspace.html Fedora documentation on swap] for a good overview on determining the right swap partition size.<br />
* 3: System - This will hold our root and home data. It will be formatted as BTRFS and will use subvolumes to manage snapshots of the current root and home contents.<br />
<br />
=== Visual overview of our partitions, filesystems, and contents ===<br />
<br />
This is a visual summary of our partions (inc. size information), encryption, filesystems, and a summary of the contents of each container.<br />
<br />
{| class="wikitable"<br />
| style="vertical-align: top; padding:1em" | '''Partition 1 (EFI)'''<br />
550MiB+<br />
{| style="border: 1px solid black; background: #DACEF2; margin: 1em;"<br />
! FAT32<br />
|-<br />
|kernel & initramfs<br />
(signed if using secure boot)<br />
|}<br />
| style="vertical-align: top; padding:1em" | '''Partition 2 (Swap)'''<br />
w/ Hibernate: Equal RAM,<br />
w/o Hibernate: min 8GB<br />
{| style="border: 1px solid black; background: #F2ECCE; margin: 1em;"<br />
|-<br />
! dm-crypt<br />
{| style="border: 1px solid black; background: #DACEF2; margin: 1em;"<br />
| SWAP<br />
|}<br />
|}<br />
| style="vertical-align: top; padding:1em" | '''Partition 3 (System)'''<br />
Remaining Space<br />
{| style="border: 1px solid black; background: #F2ECCE; margin: 1em;"<br />
|-<br />
! LUKS dm-crypt<br />
<br />
{| style="border: 1px solid black; background: #DACEF2; margin: 1em;"<br />
| BTRFS Top Level Subvolume<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Root Subvolume<br />
|}<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Home Subvolume<br />
|}<br />
<br />
{| style="border: 1px solid black; background: #E0CEF2; margin: 1em;"<br />
| BTRFS Snapshots Subvolume<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Root Snapshot Subvolume(s)<br />
|}<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Home Snapshot Subvolume(s)<br />
|}<br />
<br />
|}<br />
<br />
|}<br />
<br />
|}<br />
<br />
|}<br />
<br />
=== Partition Drive ===<br />
<br />
There are many utilities available for [[Partitioning]]. Because we are using Arch Linux and the command line doesn't hurt us (it makes us stronger) we will be using pure, non-interactive command line tools for this. Specifically, we will be using the utility [[Fdisk#Using_sgdisk|sgdisk]] from the {{Pkg|gptfdisk}} package. The [[Fdisk|fdisk]] utility now also supports GPT partitioned drives, so it would be an alternative. [[Fdisk#Using_sgdisk|sgdisk]] is available by default on the standard Arch install iso that you use to make your bootable USB drive.<br />
<br />
First, select the drive you will install to. Make sure you have selected the correct drive!. Again, a quick {{ic|lsblk}} will work here.<br />
<br />
# $DRIVE=/dev/DRIVEID<br />
<br />
(replace /dev/DRIVEID with the correct value, for example /dev/sda, /dev/nvme0n1, etc.)<br />
<br />
If you didn't securely wipe the drive already, it's worth "zapping" it using [[Fdisk#Using_sgdisk|sgdisk]] to remove any lingering legacy partition information. If you already wiped the drive you can skip this command (though it won't hurt to run it again).<br />
<br />
{{Warning|'''This command will also effectively erase the selected drive!'''}}<br />
<br />
# sgdisk --zap-all $DRIVE<br />
<br />
The following command will then create all three partitions in one go. '''It will also effectively erase the selected drive!'''<br />
<br />
# sgdisk --clear \<br />
--new=1:0:+550MiB --typecode=1:ef00 --change-name=1:EFI \<br />
--new=2:0:+8GiB --typecode=2:8200 --change-name=2:cryptswap \<br />
--new=3:0:0 --typecode=2:8200 --change-name=3:cryptsystem \<br />
$DRIVE<br />
<br />
It is worth noting that the "--change-name" values are, in this case, creating GPT "partition labels". You can subsequently see these by using the {{ic|lsblk -o +PARTLABEL}} command. It is good to use "EFI" for the efi partition. I am not aware of UEFI implementations that actively use the label for identification of the EFI partition, but it is possible that some do (UEFI bios implementations are not always consistent or to spec). The other two names are entirely "arbitrary". There is nothing special about calling them cryptswap and cryptsystem; they are simply good, clear names that remind us of the purpose of this partition and what it contains (for example, "cryptswap" suggests "this partition is for swap, and is encrypted").<br />
<br />
One final note about partition labels: we want them to be unique on your system. If for some reason there is already a GPT partition with the name EFI on another drive on your system, either change that partition name or use something besides "EFI" to avoid a namespace collision.<br />
<br />
Note also, that the backslashes at the end of each line can be omitted if you are writing the command on one long line instead. Those simply allow the splitting of a single command onto multiple lines.<br />
<br />
=== Format EFI Partition ===<br />
<br />
Next up: format the first (EFI) partition using the (required) FAT32 filesystem.<br />
<br />
# mksf.fat -F32 -n EFI /dev/disk/by-partlabel/EFI<br />
<br />
Note that we here make use of the partition label we just assigned. I prefer doing this since it simplifies scripts significantly for me and makes them, in my opinion, more readable.<br />
<br />
=== Encrypt System Partition ===<br />
<br />
Encrypt the main partition. Use a good passphrase. Note that the "--align-payload" value has been used as per [http://www.spinics.net/lists/dm-crypt/msg02421.html this suggestion/explanation] on the dm-crypt mailing list.<br />
<br />
Note also that I selected the encryption algorithm and key size using cryptsetup benchmark. See the [[Dm-crypt/Device_encryption]] article for more details.<br />
<br />
# cryptsetup luksFormat --align-payload=8192 -s 256 -c aes-xts-plain64 /dev/disk/by-partlabel/cryptsystem<br />
<br />
After creating the encrypted container, open it. Again, note the use of the partition label to identify the drive. Additionally, note that once we open this device we are giving it a name of "system." Thus "cryptsystem" is the encrypted system partition, while "system" is the name we are using once it has been opened in an unencrypted state. These names are arbitrary (Linux doesn't care what we use) but they help us keep things organized during this process.<br />
<br />
# cryptsetup open /dev/disk/by-partlabel/cryptsystem system<br />
<br />
=== Bring Up Encrypted Swap ===<br />
<br />
Finally we create encrypted swap. In this example we are not enabling hibernation. I will provide information on how to enable hibernation separately. Again, using partition labels to identify the partition and going from "cryptswap" to just "swap".<br />
<br />
We are not using LUKS here (which effectively makes dm-crypt easier to use). We're just using plain dm-crypt to encrypt the swap partition using a random key.<br />
<br />
# cryptsetup open --type plain --key-file /dev/urandom /dev/disk/by-partlabel/cryptswap swap<br />
# mkswap -L swap /dev/mapper/swap<br />
# swapon -L swap<br />
<br />
=== Create BTRFS Subvolumes ===<br />
<br />
Now on to the main attraction: creating our BTRFS subvolume structure. While BTRFS can be set up like any other filesystem (single command, just use the created file system directly), we're going to use the power of BTRFS to enable snapshotting our system state efficiently and rollbacks as necessary.<br />
<br />
First we create a top-level BTRFS subvolume. Note that the top-level entity in BTRFS nomenclature is still referred to as a '''sub'''volume, despite being at the top-level.<br />
<br />
We will create and mount this subvolume, create some new subvolumes inside it, and then switch to those subvolumes as our proper, mounted filesystems. Doing this will enable us to treat our root filesystem as a snapshotable object.<br />
<br />
Top-level subvolume creation.<br />
<br />
# mkfs.btrfs --force --label system /dev/mapper/system<br />
<br />
Temporarily mount our top-level volume for further subvolume creation. Note that the variable 'o' in this case is our default set of options for any given filesystem mount, while "o_btrfs" are those plus some options specific to btrfs. The default option "x-mount.mkdir" is a neat trick that allows us to skip the creation of directories for mountpoints (they will be created automatically). We assume /mnt as the standard mount point, as in a normal Arch Linux installation.<br />
<br />
# o=defaults,x-mount.mkdir<br />
# o_btrfs=$o,compress=lzo,ssd,noatime<br />
<br />
Note the use of our filesystem label to mount our subvolume. This is distinct from the partition labels used earlier. See the Arch wiki article on [[Persistent_block_device_naming]] for more information.<br />
<br />
# mount -t btrfs LABEL=system /mnt<br />
<br />
Now we create the subvolumes which will actually be mounted in our running system:<br />
<br />
# btrfs subvolume create /mnt/root<br />
# btrfs subvolume create /mnt/home<br />
# btrfs subvolume create /mnt/snapshots<br />
<br />
Then we unmount everything...<br />
<br />
# umount -R /mnt<br />
<br />
And remount just the subvolumes under our top-level subvolume (which remains unmounted unless we need to do "surgery" and rollback to a previous system system):<br />
<br />
# mount -t btrfs -o subvol=root,$o_btrfs LABEL=system /mnt<br />
<br />
Before mounting the home and snapshots subvolumes, let's walk through that command so we understand what it's doing:<br />
<br />
The 'mount -t btrfs' just specifies that our filesystem is of type BTRFS. This is often not necessary since mount will attempt to identify the filesystem type, but being explicit is often the best strategy with command line utilities, so we identify the type here.<br />
<br />
We use our previously defined mount options with the $o_btrfs variable and add the additional option "subvol=root" (separating it from our other defaults with a comma, of course). The next part of the command is "LABEL=system". Combined this reads as "mount the filesystem with the 'system' label, and use the 'root' subvolume within that".<br />
<br />
Finally, all this gets mounted at our install root, which in this case is "/mnt".<br />
<br />
Now let's pick back up and mount our home and snapshots subvolumes. Note that while the subvolume name is "snapshots", we will mount it at ".snapshots" (note dot prefix for the mount point). This will keep our root directory listing clean but will still make it available at a reasonable mount location.<br />
<br />
# mount -t btrfs -o subvol=home,$o_btrfs LABEL=system /mnt/home<br />
# mount -t btrfs -o subvol=snapshots,$o_btrfs LABEL=system /mnt/.snapshots<br />
<br />
It it worth noting that in each case we are telling mount to use the same filesystem, namely the one labeled "system". However in each case we are also telling it to look for a different subvolume in that filesystem (via the "subvol=" option).<br />
<br />
With this done, we can move on to installing the actual system.<br />
<br />
== Installation of Base Arch Linux System ==<br />
<br />
We are currently running off the Arch installer root filesystem. We will first use the 'pacstrap' utility to start our installation and then we will boot into our new minimal system using systemd-nspawn.<br />
<br />
=== Install base package group ===<br />
<br />
# pacstrap /mnt base<br />
<br />
=== fstab Generation and Modification ===<br />
<br />
{{Note|In a simpler, non encrypted configuration it is possible to skip making an fstab altogether due to a standard known as the [https://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/ Discoverable Partitions Spec]. However given the complexity of our encrypted, btrfs subvolume configuration, we require an fstab at this time. It is possible that in future we might feasibly do away with the fstab almost entirely in this setup (see the [https://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/#whataboutautomaticmountingofbtrfssubvolumestovarhomeandsoon 'What about automatic mounting of btrfs subvolumes'] section on that page).}}<br />
<br />
Create an [[fstab]] filesystem table file, using labels (-L) to identify the filesystems.<br />
<br />
# genfstab -L -p /mnt >> /mnt/etc/fstab<br />
<br />
I prefer to use labels as this makes the system more portable to a backup drive. You should end up with something that looks pretty close to this:<br />
<br />
{{hc|# cat /mnt/etc/fstab|<nowiki><br />
# /dev/mapper/system UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=system / btrfs rw,noatime,compress=lzo,ssd,space_cache,subvolid=257,subvol=/root,subvol=root 0 0<br />
<br />
# /dev/mapper/system UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=system /home btrfs rw,noatime,compress=lzo,ssd,space_cache,subvolid=258,subvol=/home,subvol=home 0 0<br />
<br />
# /dev/mapper/system UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=system /.snapshots btrfs rw,noatime,compress=lzo,ssd,space_cache,subvolid=259,subvol=/snapshots,subvol=snapshots 0 0<br />
<br />
# /dev/nvme0n1p1 UUID=xxxx-xxxx<br />
LABEL=EFI /boot/EFI vfat rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro 0 2<br />
<br />
# /dev/mapper/swap UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=swap none swap defaults 0 0<br />
</nowiki>}}<br />
<br />
There is one problem, however. Swap will not remount this way (the plain dm-crypt partition with a random key will not have a label when it is recreated on reboot). You will have to change that line from this:<br />
<br />
{{bc|<nowiki>LABEL=swap none swap defaults 0 0</nowiki>}}<br />
<br />
to this:<br />
<br />
{{bc|/dev/mapper/swap none swap defaults 0 0}}<br />
<br />
This will ensure that the mapped device is opened as swap successfully. The other lines may remain unchanged.<br />
<br />
==== Use {{ic|sed}} instead ====<br />
<br />
As a (scriptable) alternative to the manual editing of your {{ic|/etc/fstab}} you could use {{Man|1|sed}} to edit the file in place:<br />
<br />
# sed -i "s+LABEL=swap+/dev/mapper/swap" /etc/fstab_labels<br />
<br />
=== Boot into new system ===<br />
<br />
# systemd-nspawn -bD /mnt<br />
<br />
This will boot your new base Arch Linux system. After the standard boot messages scroll by you will be presented with a login (enter {{ic|root}} and hit enter to login).<br />
<br />
=== Generate and set locale ===<br />
<br />
Next, edit and uncomment your desired locale(s) from {{ic|/etc/locale.gen}}. We use {{ic|vi}} in the example below, but you could use a simpler editor such as {{ic|nano}} if you wish.<br />
<br />
{{hc|vi /etc/locale.gen|<nowiki><br />
...<br />
#en_PH.UTF-8 UTF-8<br />
#en_PH ISO-8859-1<br />
#en_SG.UTF-8 UTF-8<br />
#en_SG ISO-8859-1<br />
#en_US.UTF-8 UTF-8<br />
#en_US ISO-8859-1<br />
#en_ZA.UTF-8 UTF-8<br />
#en_ZA ISO-8859-1<br />
#en_ZM UTF-8<br />
...<br />
</nowiki>}}<br />
<br />
Changing it to (for en_US.UTF-8 as a locale in this example):<br />
<br />
{{bc|<nowiki><br />
...<br />
#en_PH.UTF-8 UTF-8<br />
#en_PH ISO-8859-1<br />
#en_SG.UTF-8 UTF-8<br />
#en_SG ISO-8859-1<br />
en_US.UTF-8 UTF-8<br />
#en_US ISO-8859-1<br />
#en_ZA.UTF-8 UTF-8<br />
#en_ZA ISO-8859-1<br />
#en_ZM UTF-8<br />
...<br />
</nowiki>}}<br />
<br />
Alternately one could simply append a known value to the {{ic|/etc/locale.gen}} file:<br />
<br />
# echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen<br />
<br />
After either method, one runs the {{ic|locale-gen}} command to generate the locale files:<br />
<br />
# locale-gen<br />
<br />
Finally we use {{Man|1|systemd-firstboot}} or {{Man|1|localectl}} to set the system locale. Each of these effectively does the same thing which is to simply write to {{ic|/etc/locale.conf}} (which can simply be edited directly as per standard Arch install instructions).<br />
<br />
==== With systemd-firstboot ====<br />
<br />
{{Man|1|systemd-firstboot}} will prompt us for selection from our generated locales. It will only work if there is no assigned system locale. If you wish to make changes afterward you can use {{Man|1|localectl}}<br />
<br />
# systemd-firstboot --prompt-locale<br />
<br />
==== With localectl ====<br />
<br />
This is an alternate to using {{ic|systemd-firstboot --prompt-locale}}. It may also be used subsequent to that command if further changes to the locale are desired.<br />
<br />
If you need a reminder of which locales have been installed (during this install or later during system changes), use {{ic|localectl list-locales}}:<br />
<br />
{{hc|<nowiki># localectl list-locales</nowiki>|en_US.UTF-8}}<br />
<br />
We then use {{ic|localectl set-locale}}:<br />
<br />
# localectl set-locale LANG=en_US.UTF-8<br />
<br />
=== Time and Date ===<br />
<br />
Unless you have a reason not to, we'll turn on NTP synchronization.<br />
<br />
# timedatectl set-ntp 1<br />
<br />
Then list timezones and pick one<br />
<br />
{{hc|<nowiki># timedatectl list-timezones</nowiki>|<nowiki><br />
...<br />
America/Kentucky/Louisville<br />
America/Kentucky/Monticello<br />
America/Kralendijk<br />
America/La_Paz<br />
America/Lima<br />
America/Los_Angeles<br />
America/Lower_Princes<br />
America/Maceio<br />
America/Managua<br />
America/Manaus<br />
America/Marigot<br />
America/Martinique<br />
America/Matamoros<br />
...<br />
</nowiki>}}<br />
# timedatectl set-timezone America/Los_Angeles<br />
<br />
=== Set hostname ===<br />
<br />
# hostnamectl set-hostname myhostname<br />
<br />
See the man page for {{Man|1|hostnamectl}} for other attributes that can be set. You might also add the hostname to {{Man|5|hosts}}:<br />
<br />
{{hc|/etc/hosts|<br />
127.0.0.1 localhost.localdomain localhost<br />
::1 localhost.localdomain localhost<br />
'''127.0.1.1 ''myhostname''.localdomain ''myhostname'''''<br />
}}<br />
<br />
Use {{ic|echo}} for a scriptable solution:<br />
<br />
# echo "127.0.1.1 myhostname.localdomain myhostname" >> /etc/hosts<br />
<br />
=== Network configuration ===<br />
<br />
Configure the network for the newly installed environment: see [[Network configuration]].<br />
<br />
For [[Wireless configuration]], [[Help:Reading#Installation of packages|install]] the {{Pkg|iw}}, {{Pkg|wpa_supplicant}}, and {{Pkg|dialog}} packages, as well as needed [[Wireless#Installing driver/firmware|firmware packages]].<br />
<br />
=== Base Package Installation ===<br />
<br />
We've already included the {{Grp|base}} group which is, strictly speaking, all you need to boot a minimal Arch Linux system. At this stage, however, we can install some useful utilities (and Xorg or Wayland, etc.).<br />
<br />
# pacman -Syu base-devel btrfs-progs iw gptfdisk zsh vim terminus-font<br />
<br />
=== Initramfs ===<br />
<br />
Creating a new ''initramfs'' is usually not required, because [[mkinitcpio]] was run on installation of the {{Pkg|linux}} package with ''pacstrap''.<br />
<br />
For special configurations, modify the {{man|5|mkinitcpio.conf|url=}} file and recreate the initramfs image:<br />
<br />
# mkinitcpio -p linux<br />
<br />
=== Bootloader ===<br />
<br />
<br />
<br />
=== Root password ===<br />
<br />
Set the root [[password]]:<br />
<br />
# passwd<br />
<br />
=== Leave the systemd-nspawn environment ===<br />
<br />
Issue a poweroff to exit the nspawned environment:<br />
<br />
# poweroff<br />
<br />
This will return you the Arch installer environment where you can wrap up.<br />
<br />
=== Legacy boot loader ===<br />
<br />
If your system is not UEFI and you need to use a legacy installer like grub, it will need to be installed from the Arch installer environment, not the systemd-nspawn fresh install. An example of this would be (assuming that the drive of the new system is at /dev/sdb):<br />
<br />
# grub-install --root-directory=/mnt /dev/sdb<br />
# grub-mkconfig -o /mnt/boot/grub/grub.cfg<br />
<br />
== Command Summary ==<br />
<br />
The following are all critical commands (exluded: the initial drive wipe which is optional). It assumes you have successfully brought up networking prior to starting this sequence.<br />
<br />
{{bc|<nowiki><br />
<br />
$DRIVE=/dev/DRIVEID<br />
<br />
sgdisk --zap-all $DRIVE<br />
<br />
sgdisk --clear \<br />
--new=1:0:+550MiB --typecode=1:ef00 --change-name=1:EFI \<br />
--new=2:0:+8GiB --typecode=2:8200 --change-name=2:cryptswap \<br />
--new=3:0:0 --typecode=2:8200 --change-name=3:cryptsystem \<br />
$DRIVE<br />
<br />
mksf.fat -F32 -n EFI /dev/disk/by-partlabel/EFI<br />
<br />
cryptsetup luksFormat --align-payload=8192 -s 256 -c aes-xts-plain64 /dev/disk/by-partlabel/cryptsystem<br />
<br />
cryptsetup open /dev/disk/by-partlabel/cryptsystem system<br />
<br />
cryptsetup open --type plain --key-file /dev/urandom /dev/disk/by-partlabel/cryptswap swap<br />
<br />
mkswap -L swap /dev/mapper/swap<br />
<br />
swapon -L swap<br />
<br />
mkfs.btrfs --force --label system /dev/mapper/system<br />
<br />
o=defaults,x-mount.mkdir<br />
<br />
o_btrfs=$o,compress=lzo,ssd,noatime<br />
<br />
mount -t btrfs LABEL=system /mnt<br />
<br />
btrfs subvolume create /mnt/root<br />
<br />
btrfs subvolume create /mnt/home<br />
<br />
btrfs subvolume create /mnt/snapshots<br />
<br />
umount -R /mnt<br />
<br />
mount -t btrfs -o subvol=root,$o_btrfs LABEL=system /mnt<br />
<br />
mount -t btrfs -o subvol=home,$o_btrfs LABEL=system /mnt/home<br />
<br />
mount -t btrfs -o subvol=snapshots,$o_btrfs LABEL=system /mnt/.snapshots<br />
<br />
pacstrap /mnt base<br />
<br />
genfstab -L -p /mnt >> /mnt/etc/fstab<br />
<br />
sed -i "s+LABEL=swap+/dev/mapper/swap" /etc/fstab_labels<br />
<br />
systemd-nspawn -bD /mnt<br />
<br />
echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen<br />
<br />
locale-gen<br />
<br />
localectl set-locale LANG=en_US.UTF-8<br />
<br />
timedatectl set-ntp 1<br />
<br />
timedatectl set-timezone America/Los_Angeles<br />
<br />
hostnamectl set-hostname myhostname<br />
<br />
echo "127.0.1.1 myhostname.localdomain myhostname" >> /etc/hosts<br />
<br />
pacman -Syu base-devel btrfs-progs iw gptfdisk zsh vim terminus-font<br />
</nowiki>}}</div>Altercationhttps://wiki.archlinux.org/index.php?title=User:Altercation/Bullet_Proof_Arch_Install&diff=458560User:Altercation/Bullet Proof Arch Install2016-12-05T22:12:41Z<p>Altercation: /* Command Summary */</p>
<hr />
<div>This page is a summary of the current process I follow when installing Arch on a new laptop or desktop. My process varies over time, but this serves as my "state of the art" best practice recommendations. I'm open to feedback and suggestions for improvements.<br />
<br />
{{Note|This is entirely based on my own opinions and research. It is opinionated about the best way to do things given the current state of the kernel, hardware availability, and utilities, filesystems, etc. I will explain my rationale for specific choices and provide links to other sources of information (on the Arch wiki or external) where useful.}}<br />
<br />
== Objectives ==<br />
<br />
The goals of my standard "bullet proof" Arch Linux installation are:<br />
<br />
* Benefit from Arch's rolling release model while mitigating any risk of system corruption or data loss due to failed upgrades<br />
* Minimize risk due to hardware failure or total system loss (e.g. theft or physical destruction)<br />
* Make system rollbacks easy and procedural, using a standard setup and methodology for recovery of previous system (and user data) states<br />
<br />
=== Why not the Arch Install instructions? ===<br />
<br />
The [[Installation guide|Arch Linux installation instructions]] are an excellent, general starting point and you should read and understand them. That being said, they are designed to map to a very, very broad set of installation scenarios. I am interested in a very specific type of installation (daily use desktops and laptops in this article) and I have a strong set of opinions about the "right" or "best practice" way to set up my own working systems.<br />
<br />
These instructions, then, are much more prescriptive and have strong suggestions or directions about how (and why) one should use a particular method during Arch Linux installation.<br />
<br />
=== Key differences from the stock Arch install instructions ===<br />
<br />
How these instructions differ from the standard Arch guidance:<br />
<br />
* We are encrypting the entire system but not using LVM as is often recommended (see the encryption section below for details about why we are not using it).<br />
* I use labels and avoid UUIDs where possible to make switching to an alternate recovery drive easier.<br />
* I skip arch-chroot and simply boot the new system ('''not''' reboot, just boot) from within the install environment using {{Man|1|systemd-nspawn}} which enables the *ctl commands to work (and systemd services to be enabled properly without need for a system reboot)<br />
* I use the various systemd *ctl commands (hostnamectl, timedatectl, localectl, etc.) to configure the system<br />
* I use the systemd mkinitcpio hooks in lieu of the legacy hooks.<br />
* I use BTRFS exclusively for root and home partitions for its backup capabilities.<br />
* I recommend and use secure boot (but not with the Microsoft keys) to minimize risk due to the unavoidably unencrypted EFI partition.<br />
<br />
== Assumptions ==<br />
<br />
These instructions presuppose the following:<br />
<br />
* fairly new hardware (these instructions may work on older hardware, but there may be unusual issues that crop up... if you aren't comfortable handling those situations you should consider a more "traditional" Arch Linux install (e.g. using grub, LVM, ext4, etc.)<br />
* [[Unified Extensible Firmware Interface|UEFI support]] (BIOS system install is also possible with some modification of these instructions, but this has not yet been detailed here)<br />
* probably an [[Solid State Drives|SSD]].<br />
* some familiarity with Arch, or at least some experience with Linux, will help<br />
<br />
{{Warning|I am assuming you are going to single boot (not dual boot) and that you are '''willing to wipe all data from the install drive.''' If that is not the case, do not proceed with these instructions as following them '''will effectively destroy any data (and other operating systems) on the installation target drive.'''}}<br />
<br />
== Prerequisites ==<br />
<br />
You must have a recent copy of the Arch install USB. See [[:Category:Getting and installing Arch]] for general information and [[USB flash installation media]] for specific details on creating a USB Arch installation drive.<br />
<br />
You should also have a reasonable amount of time in which to complete the installation. Novice users will want to budget a couple hours. Experienced users will ''know'' to budget a couple hours.<br />
<br />
== Preparation ==<br />
<br />
=== Boot from USB Drive ===<br />
<br />
Boot your system from your prepared [[USB flash installation media|Arch Linux USB drive]]. It is important that you boot in EFI mode, not legacy BIOS compatibility mode. See the [[Unified Extensible Firmware Interface|UEFI]] article for more information about checking boot mode and ensuring you are booting using EFI.<br />
<br />
=== Bring up the network ===<br />
<br />
If you booted into a system with an ethernet cable plugged in, chances are you're up and running. If you need to use wireless instead, {{ic|wifi-menu}} will more often than not work without trouble. If those don't work, see [[Installation guide#Connect to the Internet|the Arch installation guide section on connecting to the internet]].<br />
<br />
=== Select Drive ===<br />
<br />
I like to use the [[Core utilities#lsblk|{{ic|1=lsblk}}]] command to bring up a quick list of the block devices on the system and identify existing partition structures and sizes, as well as mount points. If you don't already use it, I recommend [[Core utilities#lsblk|{{ic|1=lsblk}}]] when you need information on any given drive or partition. It's useful for polling UUIDs as well. For example, the following command gives you a clearly formatted summary of all block devices, their partition labels, filesystem lables, UUIDs and partition UUIDS: {{ic|lsblk -o +LABEL,PARTLABEL,UUID,PARTUUID}}<br />
<br />
In any case, the plain command without options should be enough to identify the drive you will install to (for example {{ic|1=/dev/sda}} or {{ic|1=/dev/nvme0n1}}:<br />
<br />
# lsblk<br />
<br />
=== Wipe Drive Securely (optional) ===<br />
<br />
While it is not necessary, given that this process will go through the trouble of encrypting the main system partition, it makes sense to do a secure wipe of the drive. This is more or less directly from [[Dm-crypt/Drive preparation#dm-crypt wipe on an empty disk or partition]].<br />
<br />
{{Warning|Be certain of your target device selection as we will be '''wiping this drive''' (either securely or, at minimum, destroying all existing partition data).}}<br />
<br />
First, create a temporary encrypted container the full disk ({{ic|sdX}}) to be encrypted, e.g. using default encryption parameters and a random key via the {{ic|--key-file /dev/{u}random}} option (see also [[Random number generation]]):<br />
<br />
# cryptsetup open --type plain /dev/sdXY container --key-file /dev/urandom<br />
<br />
{{Note|An interesting page addressing myths about /dev/urandom can be [http://www.2uo.de/myths-about-urandom/ found here]}}<br />
<br />
Second, check the container exists:<br />
<br />
{{hc|# fdisk -l|Disk /dev/mapper/container: XXXX MB, XXXXXXXXXX bytes<br />
...<br />
Disk /dev/mapper/container does not contain a valid partition table}}<br />
Wipe the container with zeros. A use of {{ic|1=if=/dev/urandom}} is '''not''' required as the encryption cipher itself generates randomness.<br />
{{hc|# dd <nowiki>if=/dev/zero of=/dev/mapper/container status=progress bs=1M</nowiki>|<br />
dd: writing to ‘/dev/mapper/container’: No space left on device}}<br />
<br />
{{Tip|<br />
* Using ''dd'' with the {{ic|1=bs=}} option, e.g. {{ic|1=bs=1M}} as above, is frequently used to increase disk throughput of the operation.<br />
* To perform a check of the operation, zero the partition before creating the wipe container. After the wipe command {{ic|blockdev --getsize64 ''/dev/mapper/container''}} can be used to get the exact container size as root. Now ''od'' can be used to spotcheck whether the wipe overwrote the zeroed sectors, e.g. {{ic|od -j ''containersize - blocksize''}} to view the wipe completed to the end.}}<br />
<br />
Finally, close the temporary container:<br />
<br />
# cryptsetup close container<br />
<br />
== Partition & Format Drive ==<br />
<br />
=== Understanding some basics about disks, partitions, and filesystems ===<br />
<br />
Think of your drive like a big empty building, no rooms. This is your plain physical drive (either a spinning platter drive or an SSD). Next imagine that to make it useful, we divide the building into apartments. In our analogy the apartments are '''partitions''' of the drive.<br />
<br />
Imagine also that there are a couple different standard methods of creating layout maps to the apartments. These plans are standardized so that the public services that have to access the building regularly (like the fire and police, for example) understand how to find the apartment entrances. In the world of partitioning, the equivalent is the "partition table scheme". The two common schemes are called "MBR" (Master Boot Record, older) and "GPT" (GUID Partition Table, newer). We will be using the new GPT scheme.<br />
<br />
Finally, imagine that the apartments are just empty shells. The act of building walls and laying out the functional structure of the apartments is equivalent to formatting our disk partitions with a filesystem. And just as different layouts may be more or less efficient, or have other different functional characteristics, so to filesystems have different attributes that make them useful in different ways.<br />
<br />
=== Our partition plans ===<br />
<br />
We will take our physical drive and divide it into three partitions. These partitions each serve a distinct purpose. All but the first and smallest, the EFI partition, will be encrypted. For security, if your system supports Secure Boot, you may choose to cryptographically sign the data stored on the EFI partition so that any tampering will be evident, despite the lack of encryption on that partition.<br />
<br />
{{Note|Again, we're assuming an UEFI installation (not legacy BIOS) and a GPT (not MBR) partition structure. If none of that made sense, best to start with the [[Partitioning]] article or do some test installs of Arch first. '''Partitioning is, in my opinion, one of the areas that is most confusing for the new Arch user.''' Additionally, there is a lot "received wisdom" and cargo-cult assumption making about how best to partition. Working through some of the "this is how it's always been done" tutorials isn't necessarily a bad thing... In many cases the way it has always been done has some sound reasoning behind it, despite being cargo-culted half the time. That being said, the method presented here is different from that in most of the Arch wiki partitioning methodologies.}}<br />
<br />
We will not be using LVM. You read a lot about LUKS and LVM and it all gets a bit complicated (LVM on LUKS, LUKS on LVM, etc.). LVM is a "logical volume manager" and abstracts physical devices (drives) into virtual devices, for easier management. It's a good idea but we will be using btrfs to effectively achieve the same results and really don't need the overhead of LVM.<br />
<br />
=== Partition Summary ===<br />
<br />
* 1: EFI - The UEFI 'bios" will look for this FAT32 formatted partition and either locate a default bootloader or will locate a specific EFI boot entry on it. This partition is by necessity not encrypted (unless the drive it is on has been encrypted as a "self encrypting drive")<br />
* 2: Swap - Used by Linux to swap out pages of memory from RAM to disk. Despite debate in this area, it is advisable to have at least some swap space, even it you are not planning on using hibernation on your machine. The Arch wiki is unfortunately rather too brief in its own [[Swap|swap article]] so I recommend the [https://docs.fedoraproject.org/en-US/Fedora/14/html/Storage_Administration_Guide/ch-swapspace.html Fedora documentation on swap] for a good overview on determining the right swap partition size.<br />
* 3: System - This will hold our root and home data. It will be formatted as BTRFS and will use subvolumes to manage snapshots of the current root and home contents.<br />
<br />
=== Visual overview of our partitions, filesystems, and contents ===<br />
<br />
This is a visual summary of our partions (inc. size information), encryption, filesystems, and a summary of the contents of each container.<br />
<br />
{| class="wikitable"<br />
| style="vertical-align: top; padding:1em" | '''Partition 1 (EFI)'''<br />
550MiB+<br />
{| style="border: 1px solid black; background: #DACEF2; margin: 1em;"<br />
! FAT32<br />
|-<br />
|kernel & initramfs<br />
(signed if using secure boot)<br />
|}<br />
| style="vertical-align: top; padding:1em" | '''Partition 2 (Swap)'''<br />
w/ Hibernate: Equal RAM,<br />
w/o Hibernate: min 8GB<br />
{| style="border: 1px solid black; background: #F2ECCE; margin: 1em;"<br />
|-<br />
! dm-crypt<br />
{| style="border: 1px solid black; background: #DACEF2; margin: 1em;"<br />
| SWAP<br />
|}<br />
|}<br />
| style="vertical-align: top; padding:1em" | '''Partition 3 (System)'''<br />
Remaining Space<br />
{| style="border: 1px solid black; background: #F2ECCE; margin: 1em;"<br />
|-<br />
! LUKS dm-crypt<br />
<br />
{| style="border: 1px solid black; background: #DACEF2; margin: 1em;"<br />
| BTRFS Top Level Subvolume<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Root Subvolume<br />
|}<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Home Subvolume<br />
|}<br />
<br />
{| style="border: 1px solid black; background: #E0CEF2; margin: 1em;"<br />
| BTRFS Snapshots Subvolume<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Root Snapshot Subvolume(s)<br />
|}<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Home Snapshot Subvolume(s)<br />
|}<br />
<br />
|}<br />
<br />
|}<br />
<br />
|}<br />
<br />
|}<br />
<br />
=== Partition Drive ===<br />
<br />
There are many utilities available for [[Partitioning]]. Because we are using Arch Linux and the command line doesn't hurt us (it makes us stronger) we will be using pure, non-interactive command line tools for this. Specifically, we will be using the utility [[Fdisk#Using_sgdisk|sgdisk]] from the {{Pkg|gptfdisk}} package. The [[Fdisk|fdisk]] utility now also supports GPT partitioned drives, so it would be an alternative. [[Fdisk#Using_sgdisk|sgdisk]] is available by default on the standard Arch install iso that you use to make your bootable USB drive.<br />
<br />
First, select the drive you will install to. Make sure you have selected the correct drive!. Again, a quick {{ic|lsblk}} will work here.<br />
<br />
# $DRIVE=/dev/DRIVEID<br />
<br />
(replace /dev/DRIVEID with the correct value, for example /dev/sda, /dev/nvme0n1, etc.)<br />
<br />
If you didn't securely wipe the drive already, it's worth "zapping" it using [[Fdisk#Using_sgdisk|sgdisk]] to remove any lingering legacy partition information. If you already wiped the drive you can skip this command (though it won't hurt to run it again).<br />
<br />
{{Warning|'''This command will also effectively erase the selected drive!'''}}<br />
<br />
# sgdisk --zap-all $DRIVE<br />
<br />
The following command will then create all three partitions in one go. '''It will also effectively erase the selected drive!'''<br />
<br />
# sgdisk --clear \<br />
--new=1:0:+550MiB --typecode=1:ef00 --change-name=1:EFI \<br />
--new=2:0:+8GiB --typecode=2:8200 --change-name=2:cryptswap \<br />
--new=3:0:0 --typecode=2:8200 --change-name=3:cryptsystem \<br />
$DRIVE<br />
<br />
It is worth noting that the "--change-name" values are, in this case, creating GPT "partition labels". You can subsequently see these by using the {{ic|lsblk -o +PARTLABEL}} command. It is good to use "EFI" for the efi partition. I am not aware of UEFI implementations that actively use the label for identification of the EFI partition, but it is possible that some do (UEFI bios implementations are not always consistent or to spec). The other two names are entirely "arbitrary". There is nothing special about calling them cryptswap and cryptsystem; they are simply good, clear names that remind us of the purpose of this partition and what it contains (for example, "cryptswap" suggests "this partition is for swap, and is encrypted").<br />
<br />
One final note about partition labels: we want them to be unique on your system. If for some reason there is already a GPT partition with the name EFI on another drive on your system, either change that partition name or use something besides "EFI" to avoid a namespace collision.<br />
<br />
Note also, that the backslashes at the end of each line can be omitted if you are writing the command on one long line instead. Those simply allow the splitting of a single command onto multiple lines.<br />
<br />
=== Format EFI Partition ===<br />
<br />
Next up: format the first (EFI) partition using the (required) FAT32 filesystem.<br />
<br />
# mksf.fat -F32 -n EFI /dev/disk/by-partlabel/EFI<br />
<br />
Note that we here make use of the partition label we just assigned. I prefer doing this since it simplifies scripts significantly for me and makes them, in my opinion, more readable.<br />
<br />
=== Encrypt System Partition ===<br />
<br />
Encrypt the main partition. Use a good passphrase. Note that the "--align-payload" value has been used as per [http://www.spinics.net/lists/dm-crypt/msg02421.html this suggestion/explanation] on the dm-crypt mailing list.<br />
<br />
Note also that I selected the encryption algorithm and key size using cryptsetup benchmark. See the [[Dm-crypt/Device_encryption]] article for more details.<br />
<br />
# cryptsetup luksFormat --align-payload=8192 -s 256 -c aes-xts-plain64 /dev/disk/by-partlabel/cryptsystem<br />
<br />
After creating the encrypted container, open it. Again, note the use of the partition label to identify the drive. Additionally, note that once we open this device we are giving it a name of "system." Thus "cryptsystem" is the encrypted system partition, while "system" is the name we are using once it has been opened in an unencrypted state. These names are arbitrary (Linux doesn't care what we use) but they help us keep things organized during this process.<br />
<br />
# cryptsetup open /dev/disk/by-partlabel/cryptsystem system<br />
<br />
=== Bring Up Encrypted Swap ===<br />
<br />
Finally we create encrypted swap. In this example we are not enabling hibernation. I will provide information on how to enable hibernation separately. Again, using partition labels to identify the partition and going from "cryptswap" to just "swap".<br />
<br />
We are not using LUKS here (which effectively makes dm-crypt easier to use). We're just using plain dm-crypt to encrypt the swap partition using a random key.<br />
<br />
# cryptsetup open --type plain --key-file /dev/urandom /dev/disk/by-partlabel/cryptswap swap<br />
# mkswap -L swap /dev/mapper/swap<br />
# swapon -L swap<br />
<br />
=== Create BTRFS Subvolumes ===<br />
<br />
Now on to the main attraction: creating our BTRFS subvolume structure. While BTRFS can be set up like any other filesystem (single command, just use the created file system directly), we're going to use the power of BTRFS to enable snapshotting our system state efficiently and rollbacks as necessary.<br />
<br />
First we create a top-level BTRFS subvolume. Note that the top-level entity in BTRFS nomenclature is still referred to as a '''sub'''volume, despite being at the top-level.<br />
<br />
We will create and mount this subvolume, create some new subvolumes inside it, and then switch to those subvolumes as our proper, mounted filesystems. Doing this will enable us to treat our root filesystem as a snapshotable object.<br />
<br />
Top-level subvolume creation.<br />
<br />
# mkfs.btrfs --force --label system /dev/mapper/system<br />
<br />
Temporarily mount our top-level volume for further subvolume creation. Note that the variable 'o' in this case is our default set of options for any given filesystem mount, while "o_btrfs" are those plus some options specific to btrfs. The default option "x-mount.mkdir" is a neat trick that allows us to skip the creation of directories for mountpoints (they will be created automatically). We assume /mnt as the standard mount point, as in a normal Arch Linux installation.<br />
<br />
# o=defaults,x-mount.mkdir<br />
# o_btrfs=$o,compress=lzo,ssd,noatime<br />
<br />
Note the use of our filesystem label to mount our subvolume. This is distinct from the partition labels used earlier. See the Arch wiki article on [[Persistent_block_device_naming]] for more information.<br />
<br />
# mount -t btrfs LABEL=system /mnt<br />
<br />
Now we create the subvolumes which will actually be mounted in our running system:<br />
<br />
# btrfs subvolume create /mnt/root<br />
# btrfs subvolume create /mnt/home<br />
# btrfs subvolume create /mnt/snapshots<br />
<br />
Then we unmount everything...<br />
<br />
# umount -R /mnt<br />
<br />
And remount just the subvolumes under our top-level subvolume (which remains unmounted unless we need to do "surgery" and rollback to a previous system system):<br />
<br />
# mount -t btrfs -o subvol=root,$o_btrfs LABEL=system /mnt<br />
<br />
Before mounting the home and snapshots subvolumes, let's walk through that command so we understand what it's doing:<br />
<br />
The 'mount -t btrfs' just specifies that our filesystem is of type BTRFS. This is often not necessary since mount will attempt to identify the filesystem type, but being explicit is often the best strategy with command line utilities, so we identify the type here.<br />
<br />
We use our previously defined mount options with the $o_btrfs variable and add the additional option "subvol=root" (separating it from our other defaults with a comma, of course). The next part of the command is "LABEL=system". Combined this reads as "mount the filesystem with the 'system' label, and use the 'root' subvolume within that".<br />
<br />
Finally, all this gets mounted at our install root, which in this case is "/mnt".<br />
<br />
Now let's pick back up and mount our home and snapshots subvolumes. Note that while the subvolume name is "snapshots", we will mount it at ".snapshots" (note dot prefix for the mount point). This will keep our root directory listing clean but will still make it available at a reasonable mount location.<br />
<br />
# mount -t btrfs -o subvol=home,$o_btrfs LABEL=system /mnt/home<br />
# mount -t btrfs -o subvol=snapshots,$o_btrfs LABEL=system /mnt/.snapshots<br />
<br />
It it worth noting that in each case we are telling mount to use the same filesystem, namely the one labeled "system". However in each case we are also telling it to look for a different subvolume in that filesystem (via the "subvol=" option).<br />
<br />
With this done, we can move on to installing the actual system.<br />
<br />
== Installation of Base Arch Linux System ==<br />
<br />
We are currently running off the Arch installer root filesystem. We will first use the 'pacstrap' utility to start our installation and then we will boot into our new minimal system using systemd-nspawn.<br />
<br />
=== Install base package group ===<br />
<br />
# pacstrap /mnt base<br />
<br />
=== fstab Generation and Modification ===<br />
<br />
{{Note|In a simpler, non encrypted configuration it is possible to skip making an fstab altogether due to a standard known as the [https://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/ Discoverable Partitions Spec]. However given the complexity of our encrypted, btrfs subvolume configuration, we require an fstab at this time. It is possible that in future we might feasibly do away with the fstab almost entirely in this setup (see the [https://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/#whataboutautomaticmountingofbtrfssubvolumestovarhomeandsoon 'What about automatic mounting of btrfs subvolumes'] section on that page).}}<br />
<br />
Create an [[fstab]] filesystem table file, using labels (-L) to identify the filesystems.<br />
<br />
# genfstab -L -p /mnt >> /mnt/etc/fstab<br />
<br />
I prefer to use labels as this makes the system more portable to a backup drive. You should end up with something that looks pretty close to this:<br />
<br />
{{hc|# cat /mnt/etc/fstab|<nowiki><br />
# /dev/mapper/system UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=system / btrfs rw,noatime,compress=lzo,ssd,space_cache,subvolid=257,subvol=/root,subvol=root 0 0<br />
<br />
# /dev/mapper/system UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=system /home btrfs rw,noatime,compress=lzo,ssd,space_cache,subvolid=258,subvol=/home,subvol=home 0 0<br />
<br />
# /dev/mapper/system UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=system /.snapshots btrfs rw,noatime,compress=lzo,ssd,space_cache,subvolid=259,subvol=/snapshots,subvol=snapshots 0 0<br />
<br />
# /dev/nvme0n1p1 UUID=xxxx-xxxx<br />
LABEL=EFI /boot/EFI vfat rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro 0 2<br />
<br />
# /dev/mapper/swap UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=swap none swap defaults 0 0<br />
</nowiki>}}<br />
<br />
There is one problem, however. Swap will not remount this way (the plain dm-crypt partition with a random key will not have a label when it is recreated on reboot). You will have to change that line from this:<br />
<br />
{{bc|<nowiki>LABEL=swap none swap defaults 0 0</nowiki>}}<br />
<br />
to this:<br />
<br />
{{bc|/dev/mapper/swap none swap defaults 0 0}}<br />
<br />
This will ensure that the mapped device is opened as swap successfully. The other lines may remain unchanged.<br />
<br />
==== Use {{ic|sed}} instead ====<br />
<br />
As a (scriptable) alternative to the manual editing of your {{ic|/etc/fstab}} you could use {{Man|1|sed}} to edit the file in place:<br />
<br />
# sed -i "s+LABEL=swap+/dev/mapper/swap" /etc/fstab_labels<br />
<br />
=== Boot into new system ===<br />
<br />
# systemd-nspawn -bD /mnt<br />
<br />
This will boot your new base Arch Linux system. After the standard boot messages scroll by you will be presented with a login (enter {{ic|root}} and hit enter to login).<br />
<br />
=== Generate and set locale ===<br />
<br />
Next, edit and uncomment your desired locale(s) from {{ic|/etc/locale.gen}}. We use {{ic|vi}} in the example below, but you could use a simpler editor such as {{ic|nano}} if you wish.<br />
<br />
{{hc|vi /etc/locale.gen|<nowiki><br />
...<br />
#en_PH.UTF-8 UTF-8<br />
#en_PH ISO-8859-1<br />
#en_SG.UTF-8 UTF-8<br />
#en_SG ISO-8859-1<br />
#en_US.UTF-8 UTF-8<br />
#en_US ISO-8859-1<br />
#en_ZA.UTF-8 UTF-8<br />
#en_ZA ISO-8859-1<br />
#en_ZM UTF-8<br />
...<br />
</nowiki>}}<br />
<br />
Changing it to (for en_US.UTF-8 as a locale in this example):<br />
<br />
{{bc|<nowiki><br />
...<br />
#en_PH.UTF-8 UTF-8<br />
#en_PH ISO-8859-1<br />
#en_SG.UTF-8 UTF-8<br />
#en_SG ISO-8859-1<br />
en_US.UTF-8 UTF-8<br />
#en_US ISO-8859-1<br />
#en_ZA.UTF-8 UTF-8<br />
#en_ZA ISO-8859-1<br />
#en_ZM UTF-8<br />
...<br />
</nowiki>}}<br />
<br />
Alternately one could simply append a known value to the {{ic|/etc/locale.gen}} file:<br />
<br />
# echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen<br />
<br />
After either method, one runs the {{ic|locale-gen}} command to generate the locale files:<br />
<br />
# locale-gen<br />
<br />
Finally we use {{Man|1|systemd-firstboot}} or {{Man|1|localectl}} to set the system locale. Each of these effectively does the same thing which is to simply write to {{ic|/etc/locale.conf}} (which can simply be edited directly as per standard Arch install instructions).<br />
<br />
==== With systemd-firstboot ====<br />
<br />
{{Man|1|systemd-firstboot}} will prompt us for selection from our generated locales. It will only work if there is no assigned system locale. If you wish to make changes afterward you can use {{Man|1|localectl}}<br />
<br />
# systemd-firstboot --prompt-locale<br />
<br />
==== With localectl ====<br />
<br />
This is an alternate to using {{ic|systemd-firstboot --prompt-locale}}. It may also be used subsequent to that command if further changes to the locale are desired.<br />
<br />
If you need a reminder of which locales have been installed (during this install or later during system changes), use {{ic|localectl list-locales}}:<br />
<br />
{{hc|<nowiki># localectl list-locales</nowiki>|en_US.UTF-8}}<br />
<br />
We then use {{ic|localectl set-locale}}:<br />
<br />
# localectl set-locale LANG=en_US.UTF-8<br />
<br />
=== Time and Date ===<br />
<br />
Unless you have a reason not to, we'll turn on NTP synchronization.<br />
<br />
# timedatectl set-ntp 1<br />
<br />
Then list timezones and pick one<br />
<br />
{{hc|<nowiki># timedatectl list-timezones</nowiki>|<nowiki><br />
...<br />
America/Kentucky/Louisville<br />
America/Kentucky/Monticello<br />
America/Kralendijk<br />
America/La_Paz<br />
America/Lima<br />
America/Los_Angeles<br />
America/Lower_Princes<br />
America/Maceio<br />
America/Managua<br />
America/Manaus<br />
America/Marigot<br />
America/Martinique<br />
America/Matamoros<br />
...<br />
</nowiki>}}<br />
# timedatectl set-timezone America/Los_Angeles<br />
<br />
=== Set hostname ===<br />
<br />
# hostnamectl set-hostname myhostname<br />
<br />
See the man page for {{Man|1|hostnamectl}} for other attributes that can be set. You might also add the hostname to {{Man|5|hosts}}:<br />
<br />
{{hc|/etc/hosts|<br />
127.0.0.1 localhost.localdomain localhost<br />
::1 localhost.localdomain localhost<br />
'''127.0.1.1 ''myhostname''.localdomain ''myhostname'''''<br />
}}<br />
<br />
Use {{ic|echo}} for a scriptable solution:<br />
<br />
# echo "127.0.1.1 myhostname.localdomain myhostname" >> /etc/hosts<br />
<br />
=== Network configuration ===<br />
<br />
Configure the network for the newly installed environment: see [[Network configuration]].<br />
<br />
For [[Wireless configuration]], [[Help:Reading#Installation of packages|install]] the {{Pkg|iw}}, {{Pkg|wpa_supplicant}}, and {{Pkg|dialog}} packages, as well as needed [[Wireless#Installing driver/firmware|firmware packages]].<br />
<br />
=== Base Package Installation ===<br />
<br />
We've already included the {{Grp|base}} group which is, strictly speaking, all you need to boot a minimal Arch Linux system. At this stage, however, we can install some useful utilities (and Xorg or Wayland, etc.).<br />
<br />
# pacman -Syu base-devel btrfs-progs iw gptfdisk zsh vim terminus-font<br />
<br />
=== Initramfs ===<br />
<br />
Creating a new ''initramfs'' is usually not required, because [[mkinitcpio]] was run on installation of the {{Pkg|linux}} package with ''pacstrap''.<br />
<br />
For special configurations, modify the {{man|5|mkinitcpio.conf|url=}} file and recreate the initramfs image:<br />
<br />
# mkinitcpio -p linux<br />
<br />
=== Bootloader ===<br />
<br />
<br />
<br />
=== Root password ===<br />
<br />
Set the root [[password]]:<br />
<br />
# passwd<br />
<br />
=== Leave the systemd-nspawn environment ===<br />
<br />
Issue a poweroff to exit the nspawned environment:<br />
<br />
# poweroff<br />
<br />
This will return you the Arch installer environment where you can wrap up.<br />
<br />
=== Legacy boot loader ===<br />
<br />
If your system is not UEFI and you need to use a legacy installer like grub, it will need to be installed from the Arch installer environment, not the systemd-nspawn fresh install. An example of this would be (assuming that the drive of the new system is at /dev/sdb):<br />
<br />
# grub-install --root-directory=/mnt /dev/sdb<br />
# grub-mkconfig -o /mnt/boot/grub/grub.cfg<br />
<br />
== Command Summary ==<br />
<br />
The following are all critical commands (exluded: the initial drive wipe which is optional). It assumes you have successfully brought up networking prior to starting this sequence.<br />
<br />
{{bc|<nowiki><br />
# $DRIVE=/dev/DRIVEID<br />
# sgdisk --zap-all $DRIVE<br />
# sgdisk --clear \<br />
--new=1:0:+550MiB --typecode=1:ef00 --change-name=1:EFI \<br />
--new=2:0:+8GiB --typecode=2:8200 --change-name=2:cryptswap \<br />
--new=3:0:0 --typecode=2:8200 --change-name=3:cryptsystem \<br />
$DRIVE<br />
# mksf.fat -F32 -n EFI /dev/disk/by-partlabel/EFI<br />
# cryptsetup luksFormat --align-payload=8192 -s 256 -c aes-xts-plain64 /dev/disk/by-partlabel/cryptsystem<br />
# cryptsetup open /dev/disk/by-partlabel/cryptsystem system<br />
# cryptsetup open --type plain --key-file /dev/urandom /dev/disk/by-partlabel/cryptswap swap<br />
# mkswap -L swap /dev/mapper/swap<br />
# swapon -L swap<br />
# mkfs.btrfs --force --label system /dev/mapper/system<br />
# o=defaults,x-mount.mkdir<br />
# o_btrfs=$o,compress=lzo,ssd,noatime<br />
# mount -t btrfs LABEL=system /mnt<br />
# btrfs subvolume create /mnt/root<br />
# btrfs subvolume create /mnt/home<br />
# btrfs subvolume create /mnt/snapshots<br />
# umount -R /mnt<br />
# mount -t btrfs -o subvol=root,$o_btrfs LABEL=system /mnt<br />
# mount -t btrfs -o subvol=home,$o_btrfs LABEL=system /mnt/home<br />
# mount -t btrfs -o subvol=snapshots,$o_btrfs LABEL=system /mnt/.snapshots<br />
# pacstrap /mnt base<br />
# genfstab -L -p /mnt >> /mnt/etc/fstab<br />
# sed -i "s+LABEL=swap+/dev/mapper/swap" /etc/fstab_labels<br />
# systemd-nspawn -bD /mnt<br />
# echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen<br />
# locale-gen<br />
# localectl set-locale LANG=en_US.UTF-8<br />
# timedatectl set-ntp 1<br />
# timedatectl set-timezone America/Los_Angeles<br />
# hostnamectl set-hostname myhostname<br />
# echo "127.0.1.1 myhostname.localdomain myhostname" >> /etc/hosts<br />
# pacman -Syu base-devel btrfs-progs iw gptfdisk zsh vim terminus-font<br />
</nowiki>}}</div>Altercationhttps://wiki.archlinux.org/index.php?title=User:Altercation/Bullet_Proof_Arch_Install&diff=458559User:Altercation/Bullet Proof Arch Install2016-12-05T22:11:48Z<p>Altercation: /* Bring up the network */</p>
<hr />
<div>This page is a summary of the current process I follow when installing Arch on a new laptop or desktop. My process varies over time, but this serves as my "state of the art" best practice recommendations. I'm open to feedback and suggestions for improvements.<br />
<br />
{{Note|This is entirely based on my own opinions and research. It is opinionated about the best way to do things given the current state of the kernel, hardware availability, and utilities, filesystems, etc. I will explain my rationale for specific choices and provide links to other sources of information (on the Arch wiki or external) where useful.}}<br />
<br />
== Objectives ==<br />
<br />
The goals of my standard "bullet proof" Arch Linux installation are:<br />
<br />
* Benefit from Arch's rolling release model while mitigating any risk of system corruption or data loss due to failed upgrades<br />
* Minimize risk due to hardware failure or total system loss (e.g. theft or physical destruction)<br />
* Make system rollbacks easy and procedural, using a standard setup and methodology for recovery of previous system (and user data) states<br />
<br />
=== Why not the Arch Install instructions? ===<br />
<br />
The [[Installation guide|Arch Linux installation instructions]] are an excellent, general starting point and you should read and understand them. That being said, they are designed to map to a very, very broad set of installation scenarios. I am interested in a very specific type of installation (daily use desktops and laptops in this article) and I have a strong set of opinions about the "right" or "best practice" way to set up my own working systems.<br />
<br />
These instructions, then, are much more prescriptive and have strong suggestions or directions about how (and why) one should use a particular method during Arch Linux installation.<br />
<br />
=== Key differences from the stock Arch install instructions ===<br />
<br />
How these instructions differ from the standard Arch guidance:<br />
<br />
* We are encrypting the entire system but not using LVM as is often recommended (see the encryption section below for details about why we are not using it).<br />
* I use labels and avoid UUIDs where possible to make switching to an alternate recovery drive easier.<br />
* I skip arch-chroot and simply boot the new system ('''not''' reboot, just boot) from within the install environment using {{Man|1|systemd-nspawn}} which enables the *ctl commands to work (and systemd services to be enabled properly without need for a system reboot)<br />
* I use the various systemd *ctl commands (hostnamectl, timedatectl, localectl, etc.) to configure the system<br />
* I use the systemd mkinitcpio hooks in lieu of the legacy hooks.<br />
* I use BTRFS exclusively for root and home partitions for its backup capabilities.<br />
* I recommend and use secure boot (but not with the Microsoft keys) to minimize risk due to the unavoidably unencrypted EFI partition.<br />
<br />
== Assumptions ==<br />
<br />
These instructions presuppose the following:<br />
<br />
* fairly new hardware (these instructions may work on older hardware, but there may be unusual issues that crop up... if you aren't comfortable handling those situations you should consider a more "traditional" Arch Linux install (e.g. using grub, LVM, ext4, etc.)<br />
* [[Unified Extensible Firmware Interface|UEFI support]] (BIOS system install is also possible with some modification of these instructions, but this has not yet been detailed here)<br />
* probably an [[Solid State Drives|SSD]].<br />
* some familiarity with Arch, or at least some experience with Linux, will help<br />
<br />
{{Warning|I am assuming you are going to single boot (not dual boot) and that you are '''willing to wipe all data from the install drive.''' If that is not the case, do not proceed with these instructions as following them '''will effectively destroy any data (and other operating systems) on the installation target drive.'''}}<br />
<br />
== Prerequisites ==<br />
<br />
You must have a recent copy of the Arch install USB. See [[:Category:Getting and installing Arch]] for general information and [[USB flash installation media]] for specific details on creating a USB Arch installation drive.<br />
<br />
You should also have a reasonable amount of time in which to complete the installation. Novice users will want to budget a couple hours. Experienced users will ''know'' to budget a couple hours.<br />
<br />
== Preparation ==<br />
<br />
=== Boot from USB Drive ===<br />
<br />
Boot your system from your prepared [[USB flash installation media|Arch Linux USB drive]]. It is important that you boot in EFI mode, not legacy BIOS compatibility mode. See the [[Unified Extensible Firmware Interface|UEFI]] article for more information about checking boot mode and ensuring you are booting using EFI.<br />
<br />
=== Bring up the network ===<br />
<br />
If you booted into a system with an ethernet cable plugged in, chances are you're up and running. If you need to use wireless instead, {{ic|wifi-menu}} will more often than not work without trouble. If those don't work, see [[Installation guide#Connect to the Internet|the Arch installation guide section on connecting to the internet]].<br />
<br />
=== Select Drive ===<br />
<br />
I like to use the [[Core utilities#lsblk|{{ic|1=lsblk}}]] command to bring up a quick list of the block devices on the system and identify existing partition structures and sizes, as well as mount points. If you don't already use it, I recommend [[Core utilities#lsblk|{{ic|1=lsblk}}]] when you need information on any given drive or partition. It's useful for polling UUIDs as well. For example, the following command gives you a clearly formatted summary of all block devices, their partition labels, filesystem lables, UUIDs and partition UUIDS: {{ic|lsblk -o +LABEL,PARTLABEL,UUID,PARTUUID}}<br />
<br />
In any case, the plain command without options should be enough to identify the drive you will install to (for example {{ic|1=/dev/sda}} or {{ic|1=/dev/nvme0n1}}:<br />
<br />
# lsblk<br />
<br />
=== Wipe Drive Securely (optional) ===<br />
<br />
While it is not necessary, given that this process will go through the trouble of encrypting the main system partition, it makes sense to do a secure wipe of the drive. This is more or less directly from [[Dm-crypt/Drive preparation#dm-crypt wipe on an empty disk or partition]].<br />
<br />
{{Warning|Be certain of your target device selection as we will be '''wiping this drive''' (either securely or, at minimum, destroying all existing partition data).}}<br />
<br />
First, create a temporary encrypted container the full disk ({{ic|sdX}}) to be encrypted, e.g. using default encryption parameters and a random key via the {{ic|--key-file /dev/{u}random}} option (see also [[Random number generation]]):<br />
<br />
# cryptsetup open --type plain /dev/sdXY container --key-file /dev/urandom<br />
<br />
{{Note|An interesting page addressing myths about /dev/urandom can be [http://www.2uo.de/myths-about-urandom/ found here]}}<br />
<br />
Second, check the container exists:<br />
<br />
{{hc|# fdisk -l|Disk /dev/mapper/container: XXXX MB, XXXXXXXXXX bytes<br />
...<br />
Disk /dev/mapper/container does not contain a valid partition table}}<br />
Wipe the container with zeros. A use of {{ic|1=if=/dev/urandom}} is '''not''' required as the encryption cipher itself generates randomness.<br />
{{hc|# dd <nowiki>if=/dev/zero of=/dev/mapper/container status=progress bs=1M</nowiki>|<br />
dd: writing to ‘/dev/mapper/container’: No space left on device}}<br />
<br />
{{Tip|<br />
* Using ''dd'' with the {{ic|1=bs=}} option, e.g. {{ic|1=bs=1M}} as above, is frequently used to increase disk throughput of the operation.<br />
* To perform a check of the operation, zero the partition before creating the wipe container. After the wipe command {{ic|blockdev --getsize64 ''/dev/mapper/container''}} can be used to get the exact container size as root. Now ''od'' can be used to spotcheck whether the wipe overwrote the zeroed sectors, e.g. {{ic|od -j ''containersize - blocksize''}} to view the wipe completed to the end.}}<br />
<br />
Finally, close the temporary container:<br />
<br />
# cryptsetup close container<br />
<br />
== Partition & Format Drive ==<br />
<br />
=== Understanding some basics about disks, partitions, and filesystems ===<br />
<br />
Think of your drive like a big empty building, no rooms. This is your plain physical drive (either a spinning platter drive or an SSD). Next imagine that to make it useful, we divide the building into apartments. In our analogy the apartments are '''partitions''' of the drive.<br />
<br />
Imagine also that there are a couple different standard methods of creating layout maps to the apartments. These plans are standardized so that the public services that have to access the building regularly (like the fire and police, for example) understand how to find the apartment entrances. In the world of partitioning, the equivalent is the "partition table scheme". The two common schemes are called "MBR" (Master Boot Record, older) and "GPT" (GUID Partition Table, newer). We will be using the new GPT scheme.<br />
<br />
Finally, imagine that the apartments are just empty shells. The act of building walls and laying out the functional structure of the apartments is equivalent to formatting our disk partitions with a filesystem. And just as different layouts may be more or less efficient, or have other different functional characteristics, so to filesystems have different attributes that make them useful in different ways.<br />
<br />
=== Our partition plans ===<br />
<br />
We will take our physical drive and divide it into three partitions. These partitions each serve a distinct purpose. All but the first and smallest, the EFI partition, will be encrypted. For security, if your system supports Secure Boot, you may choose to cryptographically sign the data stored on the EFI partition so that any tampering will be evident, despite the lack of encryption on that partition.<br />
<br />
{{Note|Again, we're assuming an UEFI installation (not legacy BIOS) and a GPT (not MBR) partition structure. If none of that made sense, best to start with the [[Partitioning]] article or do some test installs of Arch first. '''Partitioning is, in my opinion, one of the areas that is most confusing for the new Arch user.''' Additionally, there is a lot "received wisdom" and cargo-cult assumption making about how best to partition. Working through some of the "this is how it's always been done" tutorials isn't necessarily a bad thing... In many cases the way it has always been done has some sound reasoning behind it, despite being cargo-culted half the time. That being said, the method presented here is different from that in most of the Arch wiki partitioning methodologies.}}<br />
<br />
We will not be using LVM. You read a lot about LUKS and LVM and it all gets a bit complicated (LVM on LUKS, LUKS on LVM, etc.). LVM is a "logical volume manager" and abstracts physical devices (drives) into virtual devices, for easier management. It's a good idea but we will be using btrfs to effectively achieve the same results and really don't need the overhead of LVM.<br />
<br />
=== Partition Summary ===<br />
<br />
* 1: EFI - The UEFI 'bios" will look for this FAT32 formatted partition and either locate a default bootloader or will locate a specific EFI boot entry on it. This partition is by necessity not encrypted (unless the drive it is on has been encrypted as a "self encrypting drive")<br />
* 2: Swap - Used by Linux to swap out pages of memory from RAM to disk. Despite debate in this area, it is advisable to have at least some swap space, even it you are not planning on using hibernation on your machine. The Arch wiki is unfortunately rather too brief in its own [[Swap|swap article]] so I recommend the [https://docs.fedoraproject.org/en-US/Fedora/14/html/Storage_Administration_Guide/ch-swapspace.html Fedora documentation on swap] for a good overview on determining the right swap partition size.<br />
* 3: System - This will hold our root and home data. It will be formatted as BTRFS and will use subvolumes to manage snapshots of the current root and home contents.<br />
<br />
=== Visual overview of our partitions, filesystems, and contents ===<br />
<br />
This is a visual summary of our partions (inc. size information), encryption, filesystems, and a summary of the contents of each container.<br />
<br />
{| class="wikitable"<br />
| style="vertical-align: top; padding:1em" | '''Partition 1 (EFI)'''<br />
550MiB+<br />
{| style="border: 1px solid black; background: #DACEF2; margin: 1em;"<br />
! FAT32<br />
|-<br />
|kernel & initramfs<br />
(signed if using secure boot)<br />
|}<br />
| style="vertical-align: top; padding:1em" | '''Partition 2 (Swap)'''<br />
w/ Hibernate: Equal RAM,<br />
w/o Hibernate: min 8GB<br />
{| style="border: 1px solid black; background: #F2ECCE; margin: 1em;"<br />
|-<br />
! dm-crypt<br />
{| style="border: 1px solid black; background: #DACEF2; margin: 1em;"<br />
| SWAP<br />
|}<br />
|}<br />
| style="vertical-align: top; padding:1em" | '''Partition 3 (System)'''<br />
Remaining Space<br />
{| style="border: 1px solid black; background: #F2ECCE; margin: 1em;"<br />
|-<br />
! LUKS dm-crypt<br />
<br />
{| style="border: 1px solid black; background: #DACEF2; margin: 1em;"<br />
| BTRFS Top Level Subvolume<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Root Subvolume<br />
|}<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Home Subvolume<br />
|}<br />
<br />
{| style="border: 1px solid black; background: #E0CEF2; margin: 1em;"<br />
| BTRFS Snapshots Subvolume<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Root Snapshot Subvolume(s)<br />
|}<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Home Snapshot Subvolume(s)<br />
|}<br />
<br />
|}<br />
<br />
|}<br />
<br />
|}<br />
<br />
|}<br />
<br />
=== Partition Drive ===<br />
<br />
There are many utilities available for [[Partitioning]]. Because we are using Arch Linux and the command line doesn't hurt us (it makes us stronger) we will be using pure, non-interactive command line tools for this. Specifically, we will be using the utility [[Fdisk#Using_sgdisk|sgdisk]] from the {{Pkg|gptfdisk}} package. The [[Fdisk|fdisk]] utility now also supports GPT partitioned drives, so it would be an alternative. [[Fdisk#Using_sgdisk|sgdisk]] is available by default on the standard Arch install iso that you use to make your bootable USB drive.<br />
<br />
First, select the drive you will install to. Make sure you have selected the correct drive!. Again, a quick {{ic|lsblk}} will work here.<br />
<br />
# $DRIVE=/dev/DRIVEID<br />
<br />
(replace /dev/DRIVEID with the correct value, for example /dev/sda, /dev/nvme0n1, etc.)<br />
<br />
If you didn't securely wipe the drive already, it's worth "zapping" it using [[Fdisk#Using_sgdisk|sgdisk]] to remove any lingering legacy partition information. If you already wiped the drive you can skip this command (though it won't hurt to run it again).<br />
<br />
{{Warning|'''This command will also effectively erase the selected drive!'''}}<br />
<br />
# sgdisk --zap-all $DRIVE<br />
<br />
The following command will then create all three partitions in one go. '''It will also effectively erase the selected drive!'''<br />
<br />
# sgdisk --clear \<br />
--new=1:0:+550MiB --typecode=1:ef00 --change-name=1:EFI \<br />
--new=2:0:+8GiB --typecode=2:8200 --change-name=2:cryptswap \<br />
--new=3:0:0 --typecode=2:8200 --change-name=3:cryptsystem \<br />
$DRIVE<br />
<br />
It is worth noting that the "--change-name" values are, in this case, creating GPT "partition labels". You can subsequently see these by using the {{ic|lsblk -o +PARTLABEL}} command. It is good to use "EFI" for the efi partition. I am not aware of UEFI implementations that actively use the label for identification of the EFI partition, but it is possible that some do (UEFI bios implementations are not always consistent or to spec). The other two names are entirely "arbitrary". There is nothing special about calling them cryptswap and cryptsystem; they are simply good, clear names that remind us of the purpose of this partition and what it contains (for example, "cryptswap" suggests "this partition is for swap, and is encrypted").<br />
<br />
One final note about partition labels: we want them to be unique on your system. If for some reason there is already a GPT partition with the name EFI on another drive on your system, either change that partition name or use something besides "EFI" to avoid a namespace collision.<br />
<br />
Note also, that the backslashes at the end of each line can be omitted if you are writing the command on one long line instead. Those simply allow the splitting of a single command onto multiple lines.<br />
<br />
=== Format EFI Partition ===<br />
<br />
Next up: format the first (EFI) partition using the (required) FAT32 filesystem.<br />
<br />
# mksf.fat -F32 -n EFI /dev/disk/by-partlabel/EFI<br />
<br />
Note that we here make use of the partition label we just assigned. I prefer doing this since it simplifies scripts significantly for me and makes them, in my opinion, more readable.<br />
<br />
=== Encrypt System Partition ===<br />
<br />
Encrypt the main partition. Use a good passphrase. Note that the "--align-payload" value has been used as per [http://www.spinics.net/lists/dm-crypt/msg02421.html this suggestion/explanation] on the dm-crypt mailing list.<br />
<br />
Note also that I selected the encryption algorithm and key size using cryptsetup benchmark. See the [[Dm-crypt/Device_encryption]] article for more details.<br />
<br />
# cryptsetup luksFormat --align-payload=8192 -s 256 -c aes-xts-plain64 /dev/disk/by-partlabel/cryptsystem<br />
<br />
After creating the encrypted container, open it. Again, note the use of the partition label to identify the drive. Additionally, note that once we open this device we are giving it a name of "system." Thus "cryptsystem" is the encrypted system partition, while "system" is the name we are using once it has been opened in an unencrypted state. These names are arbitrary (Linux doesn't care what we use) but they help us keep things organized during this process.<br />
<br />
# cryptsetup open /dev/disk/by-partlabel/cryptsystem system<br />
<br />
=== Bring Up Encrypted Swap ===<br />
<br />
Finally we create encrypted swap. In this example we are not enabling hibernation. I will provide information on how to enable hibernation separately. Again, using partition labels to identify the partition and going from "cryptswap" to just "swap".<br />
<br />
We are not using LUKS here (which effectively makes dm-crypt easier to use). We're just using plain dm-crypt to encrypt the swap partition using a random key.<br />
<br />
# cryptsetup open --type plain --key-file /dev/urandom /dev/disk/by-partlabel/cryptswap swap<br />
# mkswap -L swap /dev/mapper/swap<br />
# swapon -L swap<br />
<br />
=== Create BTRFS Subvolumes ===<br />
<br />
Now on to the main attraction: creating our BTRFS subvolume structure. While BTRFS can be set up like any other filesystem (single command, just use the created file system directly), we're going to use the power of BTRFS to enable snapshotting our system state efficiently and rollbacks as necessary.<br />
<br />
First we create a top-level BTRFS subvolume. Note that the top-level entity in BTRFS nomenclature is still referred to as a '''sub'''volume, despite being at the top-level.<br />
<br />
We will create and mount this subvolume, create some new subvolumes inside it, and then switch to those subvolumes as our proper, mounted filesystems. Doing this will enable us to treat our root filesystem as a snapshotable object.<br />
<br />
Top-level subvolume creation.<br />
<br />
# mkfs.btrfs --force --label system /dev/mapper/system<br />
<br />
Temporarily mount our top-level volume for further subvolume creation. Note that the variable 'o' in this case is our default set of options for any given filesystem mount, while "o_btrfs" are those plus some options specific to btrfs. The default option "x-mount.mkdir" is a neat trick that allows us to skip the creation of directories for mountpoints (they will be created automatically). We assume /mnt as the standard mount point, as in a normal Arch Linux installation.<br />
<br />
# o=defaults,x-mount.mkdir<br />
# o_btrfs=$o,compress=lzo,ssd,noatime<br />
<br />
Note the use of our filesystem label to mount our subvolume. This is distinct from the partition labels used earlier. See the Arch wiki article on [[Persistent_block_device_naming]] for more information.<br />
<br />
# mount -t btrfs LABEL=system /mnt<br />
<br />
Now we create the subvolumes which will actually be mounted in our running system:<br />
<br />
# btrfs subvolume create /mnt/root<br />
# btrfs subvolume create /mnt/home<br />
# btrfs subvolume create /mnt/snapshots<br />
<br />
Then we unmount everything...<br />
<br />
# umount -R /mnt<br />
<br />
And remount just the subvolumes under our top-level subvolume (which remains unmounted unless we need to do "surgery" and rollback to a previous system system):<br />
<br />
# mount -t btrfs -o subvol=root,$o_btrfs LABEL=system /mnt<br />
<br />
Before mounting the home and snapshots subvolumes, let's walk through that command so we understand what it's doing:<br />
<br />
The 'mount -t btrfs' just specifies that our filesystem is of type BTRFS. This is often not necessary since mount will attempt to identify the filesystem type, but being explicit is often the best strategy with command line utilities, so we identify the type here.<br />
<br />
We use our previously defined mount options with the $o_btrfs variable and add the additional option "subvol=root" (separating it from our other defaults with a comma, of course). The next part of the command is "LABEL=system". Combined this reads as "mount the filesystem with the 'system' label, and use the 'root' subvolume within that".<br />
<br />
Finally, all this gets mounted at our install root, which in this case is "/mnt".<br />
<br />
Now let's pick back up and mount our home and snapshots subvolumes. Note that while the subvolume name is "snapshots", we will mount it at ".snapshots" (note dot prefix for the mount point). This will keep our root directory listing clean but will still make it available at a reasonable mount location.<br />
<br />
# mount -t btrfs -o subvol=home,$o_btrfs LABEL=system /mnt/home<br />
# mount -t btrfs -o subvol=snapshots,$o_btrfs LABEL=system /mnt/.snapshots<br />
<br />
It it worth noting that in each case we are telling mount to use the same filesystem, namely the one labeled "system". However in each case we are also telling it to look for a different subvolume in that filesystem (via the "subvol=" option).<br />
<br />
With this done, we can move on to installing the actual system.<br />
<br />
== Installation of Base Arch Linux System ==<br />
<br />
We are currently running off the Arch installer root filesystem. We will first use the 'pacstrap' utility to start our installation and then we will boot into our new minimal system using systemd-nspawn.<br />
<br />
=== Install base package group ===<br />
<br />
# pacstrap /mnt base<br />
<br />
=== fstab Generation and Modification ===<br />
<br />
{{Note|In a simpler, non encrypted configuration it is possible to skip making an fstab altogether due to a standard known as the [https://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/ Discoverable Partitions Spec]. However given the complexity of our encrypted, btrfs subvolume configuration, we require an fstab at this time. It is possible that in future we might feasibly do away with the fstab almost entirely in this setup (see the [https://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/#whataboutautomaticmountingofbtrfssubvolumestovarhomeandsoon 'What about automatic mounting of btrfs subvolumes'] section on that page).}}<br />
<br />
Create an [[fstab]] filesystem table file, using labels (-L) to identify the filesystems.<br />
<br />
# genfstab -L -p /mnt >> /mnt/etc/fstab<br />
<br />
I prefer to use labels as this makes the system more portable to a backup drive. You should end up with something that looks pretty close to this:<br />
<br />
{{hc|# cat /mnt/etc/fstab|<nowiki><br />
# /dev/mapper/system UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=system / btrfs rw,noatime,compress=lzo,ssd,space_cache,subvolid=257,subvol=/root,subvol=root 0 0<br />
<br />
# /dev/mapper/system UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=system /home btrfs rw,noatime,compress=lzo,ssd,space_cache,subvolid=258,subvol=/home,subvol=home 0 0<br />
<br />
# /dev/mapper/system UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=system /.snapshots btrfs rw,noatime,compress=lzo,ssd,space_cache,subvolid=259,subvol=/snapshots,subvol=snapshots 0 0<br />
<br />
# /dev/nvme0n1p1 UUID=xxxx-xxxx<br />
LABEL=EFI /boot/EFI vfat rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro 0 2<br />
<br />
# /dev/mapper/swap UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=swap none swap defaults 0 0<br />
</nowiki>}}<br />
<br />
There is one problem, however. Swap will not remount this way (the plain dm-crypt partition with a random key will not have a label when it is recreated on reboot). You will have to change that line from this:<br />
<br />
{{bc|<nowiki>LABEL=swap none swap defaults 0 0</nowiki>}}<br />
<br />
to this:<br />
<br />
{{bc|/dev/mapper/swap none swap defaults 0 0}}<br />
<br />
This will ensure that the mapped device is opened as swap successfully. The other lines may remain unchanged.<br />
<br />
==== Use {{ic|sed}} instead ====<br />
<br />
As a (scriptable) alternative to the manual editing of your {{ic|/etc/fstab}} you could use {{Man|1|sed}} to edit the file in place:<br />
<br />
# sed -i "s+LABEL=swap+/dev/mapper/swap" /etc/fstab_labels<br />
<br />
=== Boot into new system ===<br />
<br />
# systemd-nspawn -bD /mnt<br />
<br />
This will boot your new base Arch Linux system. After the standard boot messages scroll by you will be presented with a login (enter {{ic|root}} and hit enter to login).<br />
<br />
=== Generate and set locale ===<br />
<br />
Next, edit and uncomment your desired locale(s) from {{ic|/etc/locale.gen}}. We use {{ic|vi}} in the example below, but you could use a simpler editor such as {{ic|nano}} if you wish.<br />
<br />
{{hc|vi /etc/locale.gen|<nowiki><br />
...<br />
#en_PH.UTF-8 UTF-8<br />
#en_PH ISO-8859-1<br />
#en_SG.UTF-8 UTF-8<br />
#en_SG ISO-8859-1<br />
#en_US.UTF-8 UTF-8<br />
#en_US ISO-8859-1<br />
#en_ZA.UTF-8 UTF-8<br />
#en_ZA ISO-8859-1<br />
#en_ZM UTF-8<br />
...<br />
</nowiki>}}<br />
<br />
Changing it to (for en_US.UTF-8 as a locale in this example):<br />
<br />
{{bc|<nowiki><br />
...<br />
#en_PH.UTF-8 UTF-8<br />
#en_PH ISO-8859-1<br />
#en_SG.UTF-8 UTF-8<br />
#en_SG ISO-8859-1<br />
en_US.UTF-8 UTF-8<br />
#en_US ISO-8859-1<br />
#en_ZA.UTF-8 UTF-8<br />
#en_ZA ISO-8859-1<br />
#en_ZM UTF-8<br />
...<br />
</nowiki>}}<br />
<br />
Alternately one could simply append a known value to the {{ic|/etc/locale.gen}} file:<br />
<br />
# echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen<br />
<br />
After either method, one runs the {{ic|locale-gen}} command to generate the locale files:<br />
<br />
# locale-gen<br />
<br />
Finally we use {{Man|1|systemd-firstboot}} or {{Man|1|localectl}} to set the system locale. Each of these effectively does the same thing which is to simply write to {{ic|/etc/locale.conf}} (which can simply be edited directly as per standard Arch install instructions).<br />
<br />
==== With systemd-firstboot ====<br />
<br />
{{Man|1|systemd-firstboot}} will prompt us for selection from our generated locales. It will only work if there is no assigned system locale. If you wish to make changes afterward you can use {{Man|1|localectl}}<br />
<br />
# systemd-firstboot --prompt-locale<br />
<br />
==== With localectl ====<br />
<br />
This is an alternate to using {{ic|systemd-firstboot --prompt-locale}}. It may also be used subsequent to that command if further changes to the locale are desired.<br />
<br />
If you need a reminder of which locales have been installed (during this install or later during system changes), use {{ic|localectl list-locales}}:<br />
<br />
{{hc|<nowiki># localectl list-locales</nowiki>|en_US.UTF-8}}<br />
<br />
We then use {{ic|localectl set-locale}}:<br />
<br />
# localectl set-locale LANG=en_US.UTF-8<br />
<br />
=== Time and Date ===<br />
<br />
Unless you have a reason not to, we'll turn on NTP synchronization.<br />
<br />
# timedatectl set-ntp 1<br />
<br />
Then list timezones and pick one<br />
<br />
{{hc|<nowiki># timedatectl list-timezones</nowiki>|<nowiki><br />
...<br />
America/Kentucky/Louisville<br />
America/Kentucky/Monticello<br />
America/Kralendijk<br />
America/La_Paz<br />
America/Lima<br />
America/Los_Angeles<br />
America/Lower_Princes<br />
America/Maceio<br />
America/Managua<br />
America/Manaus<br />
America/Marigot<br />
America/Martinique<br />
America/Matamoros<br />
...<br />
</nowiki>}}<br />
# timedatectl set-timezone America/Los_Angeles<br />
<br />
=== Set hostname ===<br />
<br />
# hostnamectl set-hostname myhostname<br />
<br />
See the man page for {{Man|1|hostnamectl}} for other attributes that can be set. You might also add the hostname to {{Man|5|hosts}}:<br />
<br />
{{hc|/etc/hosts|<br />
127.0.0.1 localhost.localdomain localhost<br />
::1 localhost.localdomain localhost<br />
'''127.0.1.1 ''myhostname''.localdomain ''myhostname'''''<br />
}}<br />
<br />
Use {{ic|echo}} for a scriptable solution:<br />
<br />
# echo "127.0.1.1 myhostname.localdomain myhostname" >> /etc/hosts<br />
<br />
=== Network configuration ===<br />
<br />
Configure the network for the newly installed environment: see [[Network configuration]].<br />
<br />
For [[Wireless configuration]], [[Help:Reading#Installation of packages|install]] the {{Pkg|iw}}, {{Pkg|wpa_supplicant}}, and {{Pkg|dialog}} packages, as well as needed [[Wireless#Installing driver/firmware|firmware packages]].<br />
<br />
=== Base Package Installation ===<br />
<br />
We've already included the {{Grp|base}} group which is, strictly speaking, all you need to boot a minimal Arch Linux system. At this stage, however, we can install some useful utilities (and Xorg or Wayland, etc.).<br />
<br />
# pacman -Syu base-devel btrfs-progs iw gptfdisk zsh vim terminus-font<br />
<br />
=== Initramfs ===<br />
<br />
Creating a new ''initramfs'' is usually not required, because [[mkinitcpio]] was run on installation of the {{Pkg|linux}} package with ''pacstrap''.<br />
<br />
For special configurations, modify the {{man|5|mkinitcpio.conf|url=}} file and recreate the initramfs image:<br />
<br />
# mkinitcpio -p linux<br />
<br />
=== Bootloader ===<br />
<br />
<br />
<br />
=== Root password ===<br />
<br />
Set the root [[password]]:<br />
<br />
# passwd<br />
<br />
=== Leave the systemd-nspawn environment ===<br />
<br />
Issue a poweroff to exit the nspawned environment:<br />
<br />
# poweroff<br />
<br />
This will return you the Arch installer environment where you can wrap up.<br />
<br />
=== Legacy boot loader ===<br />
<br />
If your system is not UEFI and you need to use a legacy installer like grub, it will need to be installed from the Arch installer environment, not the systemd-nspawn fresh install. An example of this would be (assuming that the drive of the new system is at /dev/sdb):<br />
<br />
# grub-install --root-directory=/mnt /dev/sdb<br />
# grub-mkconfig -o /mnt/boot/grub/grub.cfg<br />
<br />
== Command Summary ==<br />
<br />
The following are all critical commands (exluded: the initial drive wipe which is optional)<br />
<br />
{{bc|<nowiki><br />
# $DRIVE=/dev/DRIVEID<br />
# sgdisk --zap-all $DRIVE<br />
# sgdisk --clear \<br />
--new=1:0:+550MiB --typecode=1:ef00 --change-name=1:EFI \<br />
--new=2:0:+8GiB --typecode=2:8200 --change-name=2:cryptswap \<br />
--new=3:0:0 --typecode=2:8200 --change-name=3:cryptsystem \<br />
$DRIVE<br />
# mksf.fat -F32 -n EFI /dev/disk/by-partlabel/EFI<br />
# cryptsetup luksFormat --align-payload=8192 -s 256 -c aes-xts-plain64 /dev/disk/by-partlabel/cryptsystem<br />
# cryptsetup open /dev/disk/by-partlabel/cryptsystem system<br />
# cryptsetup open --type plain --key-file /dev/urandom /dev/disk/by-partlabel/cryptswap swap<br />
# mkswap -L swap /dev/mapper/swap<br />
# swapon -L swap<br />
# mkfs.btrfs --force --label system /dev/mapper/system<br />
# o=defaults,x-mount.mkdir<br />
# o_btrfs=$o,compress=lzo,ssd,noatime<br />
# mount -t btrfs LABEL=system /mnt<br />
# btrfs subvolume create /mnt/root<br />
# btrfs subvolume create /mnt/home<br />
# btrfs subvolume create /mnt/snapshots<br />
# umount -R /mnt<br />
# mount -t btrfs -o subvol=root,$o_btrfs LABEL=system /mnt<br />
# mount -t btrfs -o subvol=home,$o_btrfs LABEL=system /mnt/home<br />
# mount -t btrfs -o subvol=snapshots,$o_btrfs LABEL=system /mnt/.snapshots<br />
# pacstrap /mnt base<br />
# genfstab -L -p /mnt >> /mnt/etc/fstab<br />
# sed -i "s+LABEL=swap+/dev/mapper/swap" /etc/fstab_labels<br />
# systemd-nspawn -bD /mnt<br />
# echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen<br />
# locale-gen<br />
# localectl set-locale LANG=en_US.UTF-8<br />
# timedatectl set-ntp 1<br />
# timedatectl set-timezone America/Los_Angeles<br />
# hostnamectl set-hostname myhostname<br />
# echo "127.0.1.1 myhostname.localdomain myhostname" >> /etc/hosts<br />
# pacman -Syu base-devel btrfs-progs iw gptfdisk zsh vim terminus-font<br />
</nowiki>}}</div>Altercationhttps://wiki.archlinux.org/index.php?title=User:Altercation/Bullet_Proof_Arch_Install&diff=458558User:Altercation/Bullet Proof Arch Install2016-12-05T22:11:24Z<p>Altercation: /* Preparation */</p>
<hr />
<div>This page is a summary of the current process I follow when installing Arch on a new laptop or desktop. My process varies over time, but this serves as my "state of the art" best practice recommendations. I'm open to feedback and suggestions for improvements.<br />
<br />
{{Note|This is entirely based on my own opinions and research. It is opinionated about the best way to do things given the current state of the kernel, hardware availability, and utilities, filesystems, etc. I will explain my rationale for specific choices and provide links to other sources of information (on the Arch wiki or external) where useful.}}<br />
<br />
== Objectives ==<br />
<br />
The goals of my standard "bullet proof" Arch Linux installation are:<br />
<br />
* Benefit from Arch's rolling release model while mitigating any risk of system corruption or data loss due to failed upgrades<br />
* Minimize risk due to hardware failure or total system loss (e.g. theft or physical destruction)<br />
* Make system rollbacks easy and procedural, using a standard setup and methodology for recovery of previous system (and user data) states<br />
<br />
=== Why not the Arch Install instructions? ===<br />
<br />
The [[Installation guide|Arch Linux installation instructions]] are an excellent, general starting point and you should read and understand them. That being said, they are designed to map to a very, very broad set of installation scenarios. I am interested in a very specific type of installation (daily use desktops and laptops in this article) and I have a strong set of opinions about the "right" or "best practice" way to set up my own working systems.<br />
<br />
These instructions, then, are much more prescriptive and have strong suggestions or directions about how (and why) one should use a particular method during Arch Linux installation.<br />
<br />
=== Key differences from the stock Arch install instructions ===<br />
<br />
How these instructions differ from the standard Arch guidance:<br />
<br />
* We are encrypting the entire system but not using LVM as is often recommended (see the encryption section below for details about why we are not using it).<br />
* I use labels and avoid UUIDs where possible to make switching to an alternate recovery drive easier.<br />
* I skip arch-chroot and simply boot the new system ('''not''' reboot, just boot) from within the install environment using {{Man|1|systemd-nspawn}} which enables the *ctl commands to work (and systemd services to be enabled properly without need for a system reboot)<br />
* I use the various systemd *ctl commands (hostnamectl, timedatectl, localectl, etc.) to configure the system<br />
* I use the systemd mkinitcpio hooks in lieu of the legacy hooks.<br />
* I use BTRFS exclusively for root and home partitions for its backup capabilities.<br />
* I recommend and use secure boot (but not with the Microsoft keys) to minimize risk due to the unavoidably unencrypted EFI partition.<br />
<br />
== Assumptions ==<br />
<br />
These instructions presuppose the following:<br />
<br />
* fairly new hardware (these instructions may work on older hardware, but there may be unusual issues that crop up... if you aren't comfortable handling those situations you should consider a more "traditional" Arch Linux install (e.g. using grub, LVM, ext4, etc.)<br />
* [[Unified Extensible Firmware Interface|UEFI support]] (BIOS system install is also possible with some modification of these instructions, but this has not yet been detailed here)<br />
* probably an [[Solid State Drives|SSD]].<br />
* some familiarity with Arch, or at least some experience with Linux, will help<br />
<br />
{{Warning|I am assuming you are going to single boot (not dual boot) and that you are '''willing to wipe all data from the install drive.''' If that is not the case, do not proceed with these instructions as following them '''will effectively destroy any data (and other operating systems) on the installation target drive.'''}}<br />
<br />
== Prerequisites ==<br />
<br />
You must have a recent copy of the Arch install USB. See [[:Category:Getting and installing Arch]] for general information and [[USB flash installation media]] for specific details on creating a USB Arch installation drive.<br />
<br />
You should also have a reasonable amount of time in which to complete the installation. Novice users will want to budget a couple hours. Experienced users will ''know'' to budget a couple hours.<br />
<br />
== Preparation ==<br />
<br />
=== Boot from USB Drive ===<br />
<br />
Boot your system from your prepared [[USB flash installation media|Arch Linux USB drive]]. It is important that you boot in EFI mode, not legacy BIOS compatibility mode. See the [[Unified Extensible Firmware Interface|UEFI]] article for more information about checking boot mode and ensuring you are booting using EFI.<br />
<br />
=== Bring up the network ===<br />
<br />
If you booted into a system with an ethernet cable plugged in, chances are you're up and running. If you need to use wireless instead, {{ic|wifi-menu}} will more often than not work without trouble. If those don't work, see [[Installation guide#Connect to the Internet the Arch installation guide section on connecting to the internet]].<br />
<br />
=== Select Drive ===<br />
<br />
I like to use the [[Core utilities#lsblk|{{ic|1=lsblk}}]] command to bring up a quick list of the block devices on the system and identify existing partition structures and sizes, as well as mount points. If you don't already use it, I recommend [[Core utilities#lsblk|{{ic|1=lsblk}}]] when you need information on any given drive or partition. It's useful for polling UUIDs as well. For example, the following command gives you a clearly formatted summary of all block devices, their partition labels, filesystem lables, UUIDs and partition UUIDS: {{ic|lsblk -o +LABEL,PARTLABEL,UUID,PARTUUID}}<br />
<br />
In any case, the plain command without options should be enough to identify the drive you will install to (for example {{ic|1=/dev/sda}} or {{ic|1=/dev/nvme0n1}}:<br />
<br />
# lsblk<br />
<br />
=== Wipe Drive Securely (optional) ===<br />
<br />
While it is not necessary, given that this process will go through the trouble of encrypting the main system partition, it makes sense to do a secure wipe of the drive. This is more or less directly from [[Dm-crypt/Drive preparation#dm-crypt wipe on an empty disk or partition]].<br />
<br />
{{Warning|Be certain of your target device selection as we will be '''wiping this drive''' (either securely or, at minimum, destroying all existing partition data).}}<br />
<br />
First, create a temporary encrypted container the full disk ({{ic|sdX}}) to be encrypted, e.g. using default encryption parameters and a random key via the {{ic|--key-file /dev/{u}random}} option (see also [[Random number generation]]):<br />
<br />
# cryptsetup open --type plain /dev/sdXY container --key-file /dev/urandom<br />
<br />
{{Note|An interesting page addressing myths about /dev/urandom can be [http://www.2uo.de/myths-about-urandom/ found here]}}<br />
<br />
Second, check the container exists:<br />
<br />
{{hc|# fdisk -l|Disk /dev/mapper/container: XXXX MB, XXXXXXXXXX bytes<br />
...<br />
Disk /dev/mapper/container does not contain a valid partition table}}<br />
Wipe the container with zeros. A use of {{ic|1=if=/dev/urandom}} is '''not''' required as the encryption cipher itself generates randomness.<br />
{{hc|# dd <nowiki>if=/dev/zero of=/dev/mapper/container status=progress bs=1M</nowiki>|<br />
dd: writing to ‘/dev/mapper/container’: No space left on device}}<br />
<br />
{{Tip|<br />
* Using ''dd'' with the {{ic|1=bs=}} option, e.g. {{ic|1=bs=1M}} as above, is frequently used to increase disk throughput of the operation.<br />
* To perform a check of the operation, zero the partition before creating the wipe container. After the wipe command {{ic|blockdev --getsize64 ''/dev/mapper/container''}} can be used to get the exact container size as root. Now ''od'' can be used to spotcheck whether the wipe overwrote the zeroed sectors, e.g. {{ic|od -j ''containersize - blocksize''}} to view the wipe completed to the end.}}<br />
<br />
Finally, close the temporary container:<br />
<br />
# cryptsetup close container<br />
<br />
== Partition & Format Drive ==<br />
<br />
=== Understanding some basics about disks, partitions, and filesystems ===<br />
<br />
Think of your drive like a big empty building, no rooms. This is your plain physical drive (either a spinning platter drive or an SSD). Next imagine that to make it useful, we divide the building into apartments. In our analogy the apartments are '''partitions''' of the drive.<br />
<br />
Imagine also that there are a couple different standard methods of creating layout maps to the apartments. These plans are standardized so that the public services that have to access the building regularly (like the fire and police, for example) understand how to find the apartment entrances. In the world of partitioning, the equivalent is the "partition table scheme". The two common schemes are called "MBR" (Master Boot Record, older) and "GPT" (GUID Partition Table, newer). We will be using the new GPT scheme.<br />
<br />
Finally, imagine that the apartments are just empty shells. The act of building walls and laying out the functional structure of the apartments is equivalent to formatting our disk partitions with a filesystem. And just as different layouts may be more or less efficient, or have other different functional characteristics, so to filesystems have different attributes that make them useful in different ways.<br />
<br />
=== Our partition plans ===<br />
<br />
We will take our physical drive and divide it into three partitions. These partitions each serve a distinct purpose. All but the first and smallest, the EFI partition, will be encrypted. For security, if your system supports Secure Boot, you may choose to cryptographically sign the data stored on the EFI partition so that any tampering will be evident, despite the lack of encryption on that partition.<br />
<br />
{{Note|Again, we're assuming an UEFI installation (not legacy BIOS) and a GPT (not MBR) partition structure. If none of that made sense, best to start with the [[Partitioning]] article or do some test installs of Arch first. '''Partitioning is, in my opinion, one of the areas that is most confusing for the new Arch user.''' Additionally, there is a lot "received wisdom" and cargo-cult assumption making about how best to partition. Working through some of the "this is how it's always been done" tutorials isn't necessarily a bad thing... In many cases the way it has always been done has some sound reasoning behind it, despite being cargo-culted half the time. That being said, the method presented here is different from that in most of the Arch wiki partitioning methodologies.}}<br />
<br />
We will not be using LVM. You read a lot about LUKS and LVM and it all gets a bit complicated (LVM on LUKS, LUKS on LVM, etc.). LVM is a "logical volume manager" and abstracts physical devices (drives) into virtual devices, for easier management. It's a good idea but we will be using btrfs to effectively achieve the same results and really don't need the overhead of LVM.<br />
<br />
=== Partition Summary ===<br />
<br />
* 1: EFI - The UEFI 'bios" will look for this FAT32 formatted partition and either locate a default bootloader or will locate a specific EFI boot entry on it. This partition is by necessity not encrypted (unless the drive it is on has been encrypted as a "self encrypting drive")<br />
* 2: Swap - Used by Linux to swap out pages of memory from RAM to disk. Despite debate in this area, it is advisable to have at least some swap space, even it you are not planning on using hibernation on your machine. The Arch wiki is unfortunately rather too brief in its own [[Swap|swap article]] so I recommend the [https://docs.fedoraproject.org/en-US/Fedora/14/html/Storage_Administration_Guide/ch-swapspace.html Fedora documentation on swap] for a good overview on determining the right swap partition size.<br />
* 3: System - This will hold our root and home data. It will be formatted as BTRFS and will use subvolumes to manage snapshots of the current root and home contents.<br />
<br />
=== Visual overview of our partitions, filesystems, and contents ===<br />
<br />
This is a visual summary of our partions (inc. size information), encryption, filesystems, and a summary of the contents of each container.<br />
<br />
{| class="wikitable"<br />
| style="vertical-align: top; padding:1em" | '''Partition 1 (EFI)'''<br />
550MiB+<br />
{| style="border: 1px solid black; background: #DACEF2; margin: 1em;"<br />
! FAT32<br />
|-<br />
|kernel & initramfs<br />
(signed if using secure boot)<br />
|}<br />
| style="vertical-align: top; padding:1em" | '''Partition 2 (Swap)'''<br />
w/ Hibernate: Equal RAM,<br />
w/o Hibernate: min 8GB<br />
{| style="border: 1px solid black; background: #F2ECCE; margin: 1em;"<br />
|-<br />
! dm-crypt<br />
{| style="border: 1px solid black; background: #DACEF2; margin: 1em;"<br />
| SWAP<br />
|}<br />
|}<br />
| style="vertical-align: top; padding:1em" | '''Partition 3 (System)'''<br />
Remaining Space<br />
{| style="border: 1px solid black; background: #F2ECCE; margin: 1em;"<br />
|-<br />
! LUKS dm-crypt<br />
<br />
{| style="border: 1px solid black; background: #DACEF2; margin: 1em;"<br />
| BTRFS Top Level Subvolume<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Root Subvolume<br />
|}<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Home Subvolume<br />
|}<br />
<br />
{| style="border: 1px solid black; background: #E0CEF2; margin: 1em;"<br />
| BTRFS Snapshots Subvolume<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Root Snapshot Subvolume(s)<br />
|}<br />
<br />
{| style="border: 1px solid black; background: #F2E6FF; margin: 1em;"<br />
| BTRFS Home Snapshot Subvolume(s)<br />
|}<br />
<br />
|}<br />
<br />
|}<br />
<br />
|}<br />
<br />
|}<br />
<br />
=== Partition Drive ===<br />
<br />
There are many utilities available for [[Partitioning]]. Because we are using Arch Linux and the command line doesn't hurt us (it makes us stronger) we will be using pure, non-interactive command line tools for this. Specifically, we will be using the utility [[Fdisk#Using_sgdisk|sgdisk]] from the {{Pkg|gptfdisk}} package. The [[Fdisk|fdisk]] utility now also supports GPT partitioned drives, so it would be an alternative. [[Fdisk#Using_sgdisk|sgdisk]] is available by default on the standard Arch install iso that you use to make your bootable USB drive.<br />
<br />
First, select the drive you will install to. Make sure you have selected the correct drive!. Again, a quick {{ic|lsblk}} will work here.<br />
<br />
# $DRIVE=/dev/DRIVEID<br />
<br />
(replace /dev/DRIVEID with the correct value, for example /dev/sda, /dev/nvme0n1, etc.)<br />
<br />
If you didn't securely wipe the drive already, it's worth "zapping" it using [[Fdisk#Using_sgdisk|sgdisk]] to remove any lingering legacy partition information. If you already wiped the drive you can skip this command (though it won't hurt to run it again).<br />
<br />
{{Warning|'''This command will also effectively erase the selected drive!'''}}<br />
<br />
# sgdisk --zap-all $DRIVE<br />
<br />
The following command will then create all three partitions in one go. '''It will also effectively erase the selected drive!'''<br />
<br />
# sgdisk --clear \<br />
--new=1:0:+550MiB --typecode=1:ef00 --change-name=1:EFI \<br />
--new=2:0:+8GiB --typecode=2:8200 --change-name=2:cryptswap \<br />
--new=3:0:0 --typecode=2:8200 --change-name=3:cryptsystem \<br />
$DRIVE<br />
<br />
It is worth noting that the "--change-name" values are, in this case, creating GPT "partition labels". You can subsequently see these by using the {{ic|lsblk -o +PARTLABEL}} command. It is good to use "EFI" for the efi partition. I am not aware of UEFI implementations that actively use the label for identification of the EFI partition, but it is possible that some do (UEFI bios implementations are not always consistent or to spec). The other two names are entirely "arbitrary". There is nothing special about calling them cryptswap and cryptsystem; they are simply good, clear names that remind us of the purpose of this partition and what it contains (for example, "cryptswap" suggests "this partition is for swap, and is encrypted").<br />
<br />
One final note about partition labels: we want them to be unique on your system. If for some reason there is already a GPT partition with the name EFI on another drive on your system, either change that partition name or use something besides "EFI" to avoid a namespace collision.<br />
<br />
Note also, that the backslashes at the end of each line can be omitted if you are writing the command on one long line instead. Those simply allow the splitting of a single command onto multiple lines.<br />
<br />
=== Format EFI Partition ===<br />
<br />
Next up: format the first (EFI) partition using the (required) FAT32 filesystem.<br />
<br />
# mksf.fat -F32 -n EFI /dev/disk/by-partlabel/EFI<br />
<br />
Note that we here make use of the partition label we just assigned. I prefer doing this since it simplifies scripts significantly for me and makes them, in my opinion, more readable.<br />
<br />
=== Encrypt System Partition ===<br />
<br />
Encrypt the main partition. Use a good passphrase. Note that the "--align-payload" value has been used as per [http://www.spinics.net/lists/dm-crypt/msg02421.html this suggestion/explanation] on the dm-crypt mailing list.<br />
<br />
Note also that I selected the encryption algorithm and key size using cryptsetup benchmark. See the [[Dm-crypt/Device_encryption]] article for more details.<br />
<br />
# cryptsetup luksFormat --align-payload=8192 -s 256 -c aes-xts-plain64 /dev/disk/by-partlabel/cryptsystem<br />
<br />
After creating the encrypted container, open it. Again, note the use of the partition label to identify the drive. Additionally, note that once we open this device we are giving it a name of "system." Thus "cryptsystem" is the encrypted system partition, while "system" is the name we are using once it has been opened in an unencrypted state. These names are arbitrary (Linux doesn't care what we use) but they help us keep things organized during this process.<br />
<br />
# cryptsetup open /dev/disk/by-partlabel/cryptsystem system<br />
<br />
=== Bring Up Encrypted Swap ===<br />
<br />
Finally we create encrypted swap. In this example we are not enabling hibernation. I will provide information on how to enable hibernation separately. Again, using partition labels to identify the partition and going from "cryptswap" to just "swap".<br />
<br />
We are not using LUKS here (which effectively makes dm-crypt easier to use). We're just using plain dm-crypt to encrypt the swap partition using a random key.<br />
<br />
# cryptsetup open --type plain --key-file /dev/urandom /dev/disk/by-partlabel/cryptswap swap<br />
# mkswap -L swap /dev/mapper/swap<br />
# swapon -L swap<br />
<br />
=== Create BTRFS Subvolumes ===<br />
<br />
Now on to the main attraction: creating our BTRFS subvolume structure. While BTRFS can be set up like any other filesystem (single command, just use the created file system directly), we're going to use the power of BTRFS to enable snapshotting our system state efficiently and rollbacks as necessary.<br />
<br />
First we create a top-level BTRFS subvolume. Note that the top-level entity in BTRFS nomenclature is still referred to as a '''sub'''volume, despite being at the top-level.<br />
<br />
We will create and mount this subvolume, create some new subvolumes inside it, and then switch to those subvolumes as our proper, mounted filesystems. Doing this will enable us to treat our root filesystem as a snapshotable object.<br />
<br />
Top-level subvolume creation.<br />
<br />
# mkfs.btrfs --force --label system /dev/mapper/system<br />
<br />
Temporarily mount our top-level volume for further subvolume creation. Note that the variable 'o' in this case is our default set of options for any given filesystem mount, while "o_btrfs" are those plus some options specific to btrfs. The default option "x-mount.mkdir" is a neat trick that allows us to skip the creation of directories for mountpoints (they will be created automatically). We assume /mnt as the standard mount point, as in a normal Arch Linux installation.<br />
<br />
# o=defaults,x-mount.mkdir<br />
# o_btrfs=$o,compress=lzo,ssd,noatime<br />
<br />
Note the use of our filesystem label to mount our subvolume. This is distinct from the partition labels used earlier. See the Arch wiki article on [[Persistent_block_device_naming]] for more information.<br />
<br />
# mount -t btrfs LABEL=system /mnt<br />
<br />
Now we create the subvolumes which will actually be mounted in our running system:<br />
<br />
# btrfs subvolume create /mnt/root<br />
# btrfs subvolume create /mnt/home<br />
# btrfs subvolume create /mnt/snapshots<br />
<br />
Then we unmount everything...<br />
<br />
# umount -R /mnt<br />
<br />
And remount just the subvolumes under our top-level subvolume (which remains unmounted unless we need to do "surgery" and rollback to a previous system system):<br />
<br />
# mount -t btrfs -o subvol=root,$o_btrfs LABEL=system /mnt<br />
<br />
Before mounting the home and snapshots subvolumes, let's walk through that command so we understand what it's doing:<br />
<br />
The 'mount -t btrfs' just specifies that our filesystem is of type BTRFS. This is often not necessary since mount will attempt to identify the filesystem type, but being explicit is often the best strategy with command line utilities, so we identify the type here.<br />
<br />
We use our previously defined mount options with the $o_btrfs variable and add the additional option "subvol=root" (separating it from our other defaults with a comma, of course). The next part of the command is "LABEL=system". Combined this reads as "mount the filesystem with the 'system' label, and use the 'root' subvolume within that".<br />
<br />
Finally, all this gets mounted at our install root, which in this case is "/mnt".<br />
<br />
Now let's pick back up and mount our home and snapshots subvolumes. Note that while the subvolume name is "snapshots", we will mount it at ".snapshots" (note dot prefix for the mount point). This will keep our root directory listing clean but will still make it available at a reasonable mount location.<br />
<br />
# mount -t btrfs -o subvol=home,$o_btrfs LABEL=system /mnt/home<br />
# mount -t btrfs -o subvol=snapshots,$o_btrfs LABEL=system /mnt/.snapshots<br />
<br />
It it worth noting that in each case we are telling mount to use the same filesystem, namely the one labeled "system". However in each case we are also telling it to look for a different subvolume in that filesystem (via the "subvol=" option).<br />
<br />
With this done, we can move on to installing the actual system.<br />
<br />
== Installation of Base Arch Linux System ==<br />
<br />
We are currently running off the Arch installer root filesystem. We will first use the 'pacstrap' utility to start our installation and then we will boot into our new minimal system using systemd-nspawn.<br />
<br />
=== Install base package group ===<br />
<br />
# pacstrap /mnt base<br />
<br />
=== fstab Generation and Modification ===<br />
<br />
{{Note|In a simpler, non encrypted configuration it is possible to skip making an fstab altogether due to a standard known as the [https://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/ Discoverable Partitions Spec]. However given the complexity of our encrypted, btrfs subvolume configuration, we require an fstab at this time. It is possible that in future we might feasibly do away with the fstab almost entirely in this setup (see the [https://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/#whataboutautomaticmountingofbtrfssubvolumestovarhomeandsoon 'What about automatic mounting of btrfs subvolumes'] section on that page).}}<br />
<br />
Create an [[fstab]] filesystem table file, using labels (-L) to identify the filesystems.<br />
<br />
# genfstab -L -p /mnt >> /mnt/etc/fstab<br />
<br />
I prefer to use labels as this makes the system more portable to a backup drive. You should end up with something that looks pretty close to this:<br />
<br />
{{hc|# cat /mnt/etc/fstab|<nowiki><br />
# /dev/mapper/system UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=system / btrfs rw,noatime,compress=lzo,ssd,space_cache,subvolid=257,subvol=/root,subvol=root 0 0<br />
<br />
# /dev/mapper/system UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=system /home btrfs rw,noatime,compress=lzo,ssd,space_cache,subvolid=258,subvol=/home,subvol=home 0 0<br />
<br />
# /dev/mapper/system UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=system /.snapshots btrfs rw,noatime,compress=lzo,ssd,space_cache,subvolid=259,subvol=/snapshots,subvol=snapshots 0 0<br />
<br />
# /dev/nvme0n1p1 UUID=xxxx-xxxx<br />
LABEL=EFI /boot/EFI vfat rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro 0 2<br />
<br />
# /dev/mapper/swap UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br />
LABEL=swap none swap defaults 0 0<br />
</nowiki>}}<br />
<br />
There is one problem, however. Swap will not remount this way (the plain dm-crypt partition with a random key will not have a label when it is recreated on reboot). You will have to change that line from this:<br />
<br />
{{bc|<nowiki>LABEL=swap none swap defaults 0 0</nowiki>}}<br />
<br />
to this:<br />
<br />
{{bc|/dev/mapper/swap none swap defaults 0 0}}<br />
<br />
This will ensure that the mapped device is opened as swap successfully. The other lines may remain unchanged.<br />
<br />
==== Use {{ic|sed}} instead ====<br />
<br />
As a (scriptable) alternative to the manual editing of your {{ic|/etc/fstab}} you could use {{Man|1|sed}} to edit the file in place:<br />
<br />
# sed -i "s+LABEL=swap+/dev/mapper/swap" /etc/fstab_labels<br />
<br />
=== Boot into new system ===<br />
<br />
# systemd-nspawn -bD /mnt<br />
<br />
This will boot your new base Arch Linux system. After the standard boot messages scroll by you will be presented with a login (enter {{ic|root}} and hit enter to login).<br />
<br />
=== Generate and set locale ===<br />
<br />
Next, edit and uncomment your desired locale(s) from {{ic|/etc/locale.gen}}. We use {{ic|vi}} in the example below, but you could use a simpler editor such as {{ic|nano}} if you wish.<br />
<br />
{{hc|vi /etc/locale.gen|<nowiki><br />
...<br />
#en_PH.UTF-8 UTF-8<br />
#en_PH ISO-8859-1<br />
#en_SG.UTF-8 UTF-8<br />
#en_SG ISO-8859-1<br />
#en_US.UTF-8 UTF-8<br />
#en_US ISO-8859-1<br />
#en_ZA.UTF-8 UTF-8<br />
#en_ZA ISO-8859-1<br />
#en_ZM UTF-8<br />
...<br />
</nowiki>}}<br />
<br />
Changing it to (for en_US.UTF-8 as a locale in this example):<br />
<br />
{{bc|<nowiki><br />
...<br />
#en_PH.UTF-8 UTF-8<br />
#en_PH ISO-8859-1<br />
#en_SG.UTF-8 UTF-8<br />
#en_SG ISO-8859-1<br />
en_US.UTF-8 UTF-8<br />
#en_US ISO-8859-1<br />
#en_ZA.UTF-8 UTF-8<br />
#en_ZA ISO-8859-1<br />
#en_ZM UTF-8<br />
...<br />
</nowiki>}}<br />
<br />
Alternately one could simply append a known value to the {{ic|/etc/locale.gen}} file:<br />
<br />
# echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen<br />
<br />
After either method, one runs the {{ic|locale-gen}} command to generate the locale files:<br />
<br />
# locale-gen<br />
<br />
Finally we use {{Man|1|systemd-firstboot}} or {{Man|1|localectl}} to set the system locale. Each of these effectively does the same thing which is to simply write to {{ic|/etc/locale.conf}} (which can simply be edited directly as per standard Arch install instructions).<br />
<br />
==== With systemd-firstboot ====<br />
<br />
{{Man|1|systemd-firstboot}} will prompt us for selection from our generated locales. It will only work if there is no assigned system locale. If you wish to make changes afterward you can use {{Man|1|localectl}}<br />
<br />
# systemd-firstboot --prompt-locale<br />
<br />
==== With localectl ====<br />
<br />
This is an alternate to using {{ic|systemd-firstboot --prompt-locale}}. It may also be used subsequent to that command if further changes to the locale are desired.<br />
<br />
If you need a reminder of which locales have been installed (during this install or later during system changes), use {{ic|localectl list-locales}}:<br />
<br />
{{hc|<nowiki># localectl list-locales</nowiki>|en_US.UTF-8}}<br />
<br />
We then use {{ic|localectl set-locale}}:<br />
<br />
# localectl set-locale LANG=en_US.UTF-8<br />
<br />
=== Time and Date ===<br />
<br />
Unless you have a reason not to, we'll turn on NTP synchronization.<br />
<br />
# timedatectl set-ntp 1<br />
<br />
Then list timezones and pick one<br />
<br />
{{hc|<nowiki># timedatectl list-timezones</nowiki>|<nowiki><br />
...<br />
America/Kentucky/Louisville<br />
America/Kentucky/Monticello<br />
America/Kralendijk<br />
America/La_Paz<br />
America/Lima<br />
America/Los_Angeles<br />
America/Lower_Princes<br />
America/Maceio<br />
America/Managua<br />
America/Manaus<br />
America/Marigot<br />
America/Martinique<br />
America/Matamoros<br />
...<br />
</nowiki>}}<br />
# timedatectl set-timezone America/Los_Angeles<br />
<br />
=== Set hostname ===<br />
<br />
# hostnamectl set-hostname myhostname<br />
<br />
See the man page for {{Man|1|hostnamectl}} for other attributes that can be set. You might also add the hostname to {{Man|5|hosts}}:<br />
<br />
{{hc|/etc/hosts|<br />
127.0.0.1 localhost.localdomain localhost<br />
::1 localhost.localdomain localhost<br />
'''127.0.1.1 ''myhostname''.localdomain ''myhostname'''''<br />
}}<br />
<br />
Use {{ic|echo}} for a scriptable solution:<br />
<br />
# echo "127.0.1.1 myhostname.localdomain myhostname" >> /etc/hosts<br />
<br />
=== Network configuration ===<br />
<br />
Configure the network for the newly installed environment: see [[Network configuration]].<br />
<br />
For [[Wireless configuration]], [[Help:Reading#Installation of packages|install]] the {{Pkg|iw}}, {{Pkg|wpa_supplicant}}, and {{Pkg|dialog}} packages, as well as needed [[Wireless#Installing driver/firmware|firmware packages]].<br />
<br />
=== Base Package Installation ===<br />
<br />
We've already included the {{Grp|base}} group which is, strictly speaking, all you need to boot a minimal Arch Linux system. At this stage, however, we can install some useful utilities (and Xorg or Wayland, etc.).<br />
<br />
# pacman -Syu base-devel btrfs-progs iw gptfdisk zsh vim terminus-font<br />
<br />
=== Initramfs ===<br />
<br />
Creating a new ''initramfs'' is usually not required, because [[mkinitcpio]] was run on installation of the {{Pkg|linux}} package with ''pacstrap''.<br />
<br />
For special configurations, modify the {{man|5|mkinitcpio.conf|url=}} file and recreate the initramfs image:<br />
<br />
# mkinitcpio -p linux<br />
<br />
=== Bootloader ===<br />
<br />
<br />
<br />
=== Root password ===<br />
<br />
Set the root [[password]]:<br />
<br />
# passwd<br />
<br />
=== Leave the systemd-nspawn environment ===<br />
<br />
Issue a poweroff to exit the nspawned environment:<br />
<br />
# poweroff<br />
<br />
This will return you the Arch installer environment where you can wrap up.<br />
<br />
=== Legacy boot loader ===<br />
<br />
If your system is not UEFI and you need to use a legacy installer like grub, it will need to be installed from the Arch installer environment, not the systemd-nspawn fresh install. An example of this would be (assuming that the drive of the new system is at /dev/sdb):<br />
<br />
# grub-install --root-directory=/mnt /dev/sdb<br />
# grub-mkconfig -o /mnt/boot/grub/grub.cfg<br />
<br />
== Command Summary ==<br />
<br />
The following are all critical commands (exluded: the initial drive wipe which is optional)<br />
<br />
{{bc|<nowiki><br />
# $DRIVE=/dev/DRIVEID<br />
# sgdisk --zap-all $DRIVE<br />
# sgdisk --clear \<br />
--new=1:0:+550MiB --typecode=1:ef00 --change-name=1:EFI \<br />
--new=2:0:+8GiB --typecode=2:8200 --change-name=2:cryptswap \<br />
--new=3:0:0 --typecode=2:8200 --change-name=3:cryptsystem \<br />
$DRIVE<br />
# mksf.fat -F32 -n EFI /dev/disk/by-partlabel/EFI<br />
# cryptsetup luksFormat --align-payload=8192 -s 256 -c aes-xts-plain64 /dev/disk/by-partlabel/cryptsystem<br />
# cryptsetup open /dev/disk/by-partlabel/cryptsystem system<br />
# cryptsetup open --type plain --key-file /dev/urandom /dev/disk/by-partlabel/cryptswap swap<br />
# mkswap -L swap /dev/mapper/swap<br />
# swapon -L swap<br />
# mkfs.btrfs --force --label system /dev/mapper/system<br />
# o=defaults,x-mount.mkdir<br />
# o_btrfs=$o,compress=lzo,ssd,noatime<br />
# mount -t btrfs LABEL=system /mnt<br />
# btrfs subvolume create /mnt/root<br />
# btrfs subvolume create /mnt/home<br />
# btrfs subvolume create /mnt/snapshots<br />
# umount -R /mnt<br />
# mount -t btrfs -o subvol=root,$o_btrfs LABEL=system /mnt<br />
# mount -t btrfs -o subvol=home,$o_btrfs LABEL=system /mnt/home<br />
# mount -t btrfs -o subvol=snapshots,$o_btrfs LABEL=system /mnt/.snapshots<br />
# pacstrap /mnt base<br />
# genfstab -L -p /mnt >> /mnt/etc/fstab<br />
# sed -i "s+LABEL=swap+/dev/mapper/swap" /etc/fstab_labels<br />
# systemd-nspawn -bD /mnt<br />
# echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen<br />
# locale-gen<br />
# localectl set-locale LANG=en_US.UTF-8<br />
# timedatectl set-ntp 1<br />
# timedatectl set-timezone America/Los_Angeles<br />
# hostnamectl set-hostname myhostname<br />
# echo "127.0.1.1 myhostname.localdomain myhostname" >> /etc/hosts<br />
# pacman -Syu base-devel btrfs-progs iw gptfdisk zsh vim terminus-font<br />
</nowiki>}}</div>Altercation