"Back in my day…"
…Linux was 50MB. The entire server. Today? Eleventy-billion GB.
Well, that's the story with what I call Noob Linux (aka Ubuntu). I wrote off RedHat for years because of the insanity of the size (multiple CDs in the 90s). Today Ubuntu is the new RedHat in that regard @@footnote|redhat@@.
Debian didn't buy into the bloat entirely; it's still nice. Yet, for me, there's a new kid on the block that was able to release my Debian death-grip: Arch Linux.
It's powerful. It's simple to use. It has a proper level of complexity to allow customization. The levels of porcelain and plumbing are quite balanced. Modern "Microsoft stack" developers get this. This is what C# is all about. This is what Azure is all about.
Now, how does one setup Arch linux? Answer: manually. Once you get through this, you've effectively paid your dues.
I'll give some commentary along the way. I generally follow the motto: if you can't repeat it, you can't do it. "I did it once" means nothing (this is why skill > experience). Don't rely on luck or "HOLY CRAP IT WORKS. NOBODY TOUCH IT".
You're going to be in the console. Linux uses a console. A GUI on Linux is not Linux. It's heresy. So, know these:
CTRL-A: beginning of line
CTRL-E: end of line
ESC then left-arrow: go back one word
ESC then right-arrow: go forward one word
If backspace gives you weird characters, hold
CTRLwhile hitting backspace.
For passwords, use the numbers above your letters, not on the keypad. This might (donno) be the case in a few places.
You are not ready to be awesome.
When you first mount your disc and start your VM (it's a good assumption), you'll get a screen…
…then a prompt. Let's run with that…
First, let's setup our disk. This is the same thing you're going to do in Windows, but Linux is all about more control:
What disk do you want to play with? Let's find out:
# fdisk -l
Note: this is for MBR. For GUID partitions, use
/dev/sdb stuff? Those are your disks: a and b (and c and d, etc…).
Look at the sizes deduce which one to use. You have to do the same on Windows. I've many disks. My boot SSD is much smaller than the others; that's how I know which disk to use.
Now, get into
fdisk (it's a cli).
# fdisk /dev/sda
I'm going to demonstrate two different methods for the swap space. So skim both before playing with anything.
We want to create three partitions:
- 500MB - boot
- 4GB - swap (size recommendations)
- rest of the disk
Regarding the 4GB swap partition, don't do the typical Microsoft developer "lol guidelines are for noooooooooooooooobs ima do what feels goodz. nobody has eeeeeeeever done this before so ima be a pioneerz" nonsense. Reference the size recommendations to see if 4G was right for you. RTFM! (that's reference the freggin manual-- nobody should ever read a manual like it's a Tolstoy novel)
Here are the commands in series:
n, +500M, n, +4G, t, 2, 82, n, w.
You're going to use a lot of the defaults (e.g. partition number and start sector). Reference the following image sample:
Honestly, it's better if you play with this until it makes sense. Holding your hand won't help you in the long run. Learning comes from mistakes. Make those mistakes… and create VM snapshots.
#(MBR; use gdisk for GUID paritions) (250 to 500M for boot, then RAM-sized swap, then /) n (new partition) (enter=defaults) t (change type) (82 swap) w (write/save)
Alternatively, you could use
gdisk (for GUID partitions). Same idea.
Now… let's format these (
ext3 is fine too):
# format partition 3 mkfs.ext4 /dev/sda3 # format partition 1 mkfs.ext4 /dev/sda1
We are skipping partition 2 for now. That's a swap partition. That a different paradigm entirely.
Next, we will mount these.
The big partition first…
mount /dev/sda3 /mnt
We mount this as
/ because are currently in a system that using
/. Windows splits the world up into separate drives via letter whereas Unix/Linux (hereafter just "Linux") systems use a unified naming system. In Windows you can change drive letters; in Linux you change mount points.
With this mounted, we will create a place for boot partition to mount:
Then mount the boot partition:
mount /dev/sda1 /mnt/boot
What about the 4GB partition? That's the swap partition. We treat it differently. We create the swap area then use it.
mkswap /dev/sda2 swapon /dev/sda2
Havinag said this, there's another way to handle swap space, a more modern-world / VM / dev environment compatible method: don't create an entire swap partition.
The alternative to a swap partition is a swap file. In this paradigm, don't create a swap partition. Just create your 500M boot partition and your *MB data partition.
This works here because we are using ext4. Do not try this with btrfs.
Then, instead of creating a 4G monster swap partition, let's create a smaller 512M swap file:
fallocate -l 512M /swp
Let's make it so that only the file owner (in this case, the file creator: root) can read and write it:
chmod 600 /swp
Now we can do our other commands:
mkswap /swp swapon /swp
See https://wiki.archlinux.org/index.php/Swap for more information.
We are now at the point where we install the base system. This is where it's really cool: you choose what to install. Personally, I've a few things I want to install right away so I don't have to deal with them later:
Here's my full command @@footnote|pacstrapbasedevel@@ @@footnote|pacstraplinux@@:
pacstrap -i /mnt base base-devel grub-bios openssh sudo
This command also tell you something important: whether you are on the Internet or not.
- Base system
- Basic dev tools
- Kernely stuff
- Boot manager
- OpenSSH server
- sudo (to run commands as root)
In case you're curious, here's what's inside base:
We're almost done with the system setup.
We need to tell the system about our mount points. There's a tool for that.
genfstab -U -p /mnt >> /mnt/etc/fstab
-U is important. Instead of mapping to
/dev/sda1, you're telling the system to use a GUID. This removes the risk of things moving around. See SOF for more information.
If you did did the swap file method instead of the swap partition method: you also need to run the following:
echo "/swp none swap defaults 0 0" >> /mnt/etc/fstab
This will save make sure that /swp is used on boot.
General Linux advice: during any setup always ask yourself if it needs to be something that starts on boot. Different different Linux distros will have different setups. As you'll see in a moment, Arch Linux follows the "systemctl enable X" method.
Now we need to do some stuff that presupposes your system is mounted at
/. So, we need to change our root:
Change your password:
Let's create a boot optimizer:
mkinitcpio -p linux
Magic voodoo? No. That doesn't exist. That's fiction. Well, ok, a technology advanced enough… is magic… or something.
So, you've special drivers needed to use your disk. Where are the drivers? On… the… disk. Lovely. Well… computer architecture to the rescue:
Note: this is only for MBR. More modern systems use entirely different mechanics.
When you turn on a computer, at some point the bios is going to know what disk you want to boot from (you know, that setting you set in the F2/F10/del screen). When it gives to your hard drive, it will look in the first 512 bytes for some type of instruction of what to do. This 512 byte area is the Master Boot Record.
It's a fun activity to play with this 512 byte area. You can write a quick assembler tool to have your own mini-OS. Here's a fun tutorial… Its uses 16-bit registers (e.g. AX, BX), so it's a fun flashback for many of us.
Anyway… Linux has this little image that mkinitcpio creates that contains the drivers 'n stuff needed to boot your system. [See reddit for more info](
OK, let's use the boot loader to tell it how to boot:
Now to save the related config:
grub-mkconfig -o /boot/grub/grub.cfg
We're done. Let's exit chroot, unmount, and reboot. Remember to unmount your ISO / remove disc.
exit umount -R /mnt reboot
Phase 2 Installation
Done? No. Sure you can boot, but you're about to login as root. Dude… no.
There's more to do, but I hate the idea of doing it on a console. In Hyper-V, you're not at a place where you can copy/paste. So, let's turn on networking and SSH into the server.
First, get the DHCP client doing something:
You'll probably see some scary looking "no carrier" nonsense. Ignore it.
Wait a few seconds. Then try
ip addr. No IP yet? Wait longer and run
ip addr again.
Now what? Well, we SSH into our server. But… we never made a user. Yeah, so, I cheat…
You can do this one in command with the following:
echo " PermitRootLogin yes " >> /etc/ssh/sshd_config
This will allow root to SSH into your server.
We'll remove this a little later. Chill out.
Anyway, now to start OpenSSH:
systemctl restart sshd
Just so we don't forget, let's set OpenSSH to auto start on boot:
systemctl enable sshd
You can now SSH into your server as root. Do it.
How? Answer: get an SSH client. The popular one is putty. I can't stand putty. I do keep it in my Windows folder for quick access from
Win-R, but only as a backup. I personally prefer SecureCRT. I definitely find it worth the money.
The rest of this is mostly copy/paste.
Let's create a user with the appropriate groups:
useradd -m -g users -G wheel,storage,power -s /bin/bash user01
That command asks you for a password, so you're not going to be able to simply paste it with a bunch of other subsequent commands into SSH.
However, the rest of this can be copy/pasted in:
# sudo users echo "%wheel ALL=(ALL) ALL" >> /etc/sudoers # hostname echo "arch" > /etc/hostname # localization echo LANG="en_US.UTF-8" >> /etc/locale.conf echo LC_COLLATE="C" >> /etc/locale.conf echo LC_TIME="en_US.UTF-8" >> /etc/locale.conf echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen export LANG=en_US.UTF-8 locale-gen # clock ln -sf /usr/share/zoneinfo/America/Chicago /etc/localtime hwclock --systohc --utc # name servers echo "nameserver 126.96.36.199 nameserver 188.8.131.52" > /etc/resolv.conf # makeflags; 8 cores echo "export MAKEFLAGS='-j 8'" >> /etc/bash.bashrc
The first command tells
sudo to allow anyone in the wheel group to be able to run root commands. What's with the wheel name? SOF has an answer/theory for that one.
The only other command that probably requires commentary is the
MAKEFLAGS line. This tells
gcc the system how many cores to use. Many installations require gcc, including modules installed with Python's
pip. So, don't think you're off the hook.
Almost done. Exit SSH. Reconnect. Login as the new user.
If that works, you can disable root for SSH.
Don't skip this step.
I don't like to prefix all my commands with
sudo, so I just run
bash as root:
The following command will remove the ssh-as-root line:
sed -i '/PermitRootLogin yes/d' /etc/ssh/sshd_config
For more info on the awesome tool called
sed, there's a great compilation called USEFUL ONE-LINE SCRIPTS FOR SED that you should definitely bookmark. Also, visit the parent site. It's mostly art nonsense, but the docs section has good things.
Then restart OpenSSH:
systemctl restart sshd
At this point I like to install a bunch of other stuff. We do this with
pacman. This is like
apt-get in the Debian world. Actually, it's more like a merger of
apt-cache, and other things.
Here's what's in my usual toolbox:
pacman -S mlocate wget gcc openssh make mercurial git bc curl vim dnsutils whois net-tools lsof --noconfirm
Some of that is already installed (e.g. openssh), but nobody cares. The list is more for my memory than for pacman.
The main thing left to do is to get DHCP to run automatically on boot.
Let's see what our interfaces are:
You could also use the following to get your interfaces:
You'll find that various parts of the file-system aren't really files, but very similar to the Windows WMI interfaces.
I've lo and eth0, yours might be enp3s0.
Now to enable DHCP for that interface:
systemctl enable email@example.com
You could simply do this for everything, but let's be specific (you might want to play with static on a different interface).
systemctl enable dhcpcd.service
Let's try static IPs now. It's actually a bit easier than you read in the docs:
echo "Description='A basic static ethernet connection' Interface=eth0 Connection=ethernet IP=static Address=('10.1.211.10/16' '10.1.211.11/16' '10.1.211.12/16' '10.1.211.13/16') Gateway='10.1.1.254' " > /etc/netctl/home-static netctl enable home-static