2025-2-15 Linux From Nothing Internet From Scratch

You should go there Linux From Nothing as this is my script and it may contain thing unrelated to LFN.

2. Internet From scratch

You may need:

sudo apt install libcap-dev

cd LFN

Want to start from here? Here is the image: https://d2xw7bkejy3jlh.cloudfront.net/disk.img.xz

Lets start by mounting our disk and FS:

sudo losetup -fP --show disk.img
sudo mount /dev/loop#p1 /mnt

This section is build with more details to take you through the process of making the system work, so you can apply the same logic for your own software.

Iproute2

Iproute2 is the default network tool for linux, and with it, we will be connection our LFN to the network.

git clone --depth 1 https://github.com/iproute2/iproute2.git
cd iproute2

./configure --libbpf_force=off --prefix=/usr

nano config.mk

Edit this line from y→n

HAVE_SELINUX:=n

Compile and check which libs we need to make this work!

make -j8

ldd ip/ip

We have a couple of missing libs:

  • linux-vdso.so.1 (0x00007ffc1812b000)
  • libelf.so.1
  • libcap.so.2
  • libc.so.6
  • libz.so.1
  • libzstd.so.1
  • /lib64/ld-linux-x86-64.so.2

Lets install them!

sudo make DESTDIR="/mnt" install
cd ..

ElfUtils

ElfUtils will provide libelf and simple elf editing tools.

git clone --depth 1 git://sourceware.org/git/elfutils.git
cd elfutils

autoreconf -i -f

autoreconf is an automated way to generate a configure file, here is the options:

-f--force

consider all files obsolete

-i--install

copy missing auxiliary files

cd ..
mkdir elfutils-build
cd elfutils-build

../elfutils/configure --enable-maintainer-mode --prefix=/usr

make -j8
sudo make DESTDIR="/mnt" install

cd ..

LibCap

https://sites.google.com/site/fullycapable/

LibCap is a privilege/permission lib that is a default in ... all distros!

git clone --depth 1 https://git.kernel.org/pub/scm/libs/libcap/libcap.git
cd libcap

make -j8
sudo make DESTDIR="/mnt" install

cd ..

Zlib

Zlib is a compression lib, it provides libz.

wget https://zlib.net/current/zlib.tar.gz

tar -xvzf zlib.tar.gz

mkdir zlib-build
cd zlib-build

../zlib-1.3.1/configure --prefix=/usr

make -j8
sudo make DESTDIR="/mnt" install

cd ..

Zstd (Zstandard)

https://github.com/facebook/zstd

Zstd is a compression lib/program that can produce and decode .zst .gz .xz .lz4 . Provides libzstd.

git clone --depth 1 https://github.com/facebook/zstd
cd zstd

make -j8
sudo make DESTDIR="/mnt" prefix=/usr install

cd ..

First test

Lets Sync to test it!

sync
sync
sync

sudo umount /mnt
sudo losetup -d /dev/loop#
qemu-system-x86_64 disk.img

Lets try our command:

ip
	Cannot open netlink socket: Function not implemented

We have missing kernel option, lets fix that!

Mount everything back up:

sudo losetup -fP --show disk.img
sudo mount /dev/loop#p1 /mnt

Kernel options

if you downloaded the pre-made image, you will need to follow the first #Kernel part.

cd linux
make menuconfig

General setup --->

----[*] Configure standard kernel features (expert users) --->

--------[*] Enable futex support

General architecture-dependent options --->

----[*] Provide system calls for 32-bit time_t

[*] Networking support --->

----Networking options --->

--------[*] Packet socket

--------[*] Unix domain sockets

--------[*] TCP/IP networking

Device Drivers --->

----[*] Network device support --->

--------[*] Ethernet driver support (NEW) ---> (THIS IS ALREADY MARKED)

------------[*] Intel(R) PRO/1000 Gigabit Ethernet support

File systems --->

----[*] Inotify support for userspace


Lets compile again and mv to our LFN.

make -j8
sudo mv arch/x86/boot/bzImage /mnt/boot/
cd ..

Second test

Lets Sync to test it!

sync
sync
sync

sudo umount /mnt
sudo losetup -d /dev/loop#
qemu-system-x86_64 disk.img

On your LFN:

ip
	Works!
ip link
	Works!

Mount everything back up:

sudo losetup -fP --show disk.img
sudo mount /dev/loop#p1 /mnt

Wget

https://www.gnu.org/software/wget/

Wget will allow us to start downloading thing.

wget https://ftp.gnu.org/gnu/wget/wget-latest.tar.gz

tar -xvzf wget-latest.tar.gz

mkdir wget-build
cd wget-build

../wget-1.25.0/configure --with-ssl=openssl --prefix=/usr

--with-ssl=openssl is there to avoid GnuTLS which we don't/won't have.

make -j8
sudo make DESTDIR="/mnt" install

ldd /mnt/bin/wget

libs needed (will highlight missing ones and keep in mind that you can run this in LFN as we have ldd installed):

  • linux-vdso.so.1
  • libpcre2-8.so.0 regular expression pattern matching
  • libuuid.so.1
  • libssl.so.3 OpenSSL
  • libcrypto.so.3 OpenSSL
  • libz.so.1
  • libc.so.6
  • /lib64/ld-linux-x86-64.so.2
  • cd ..
    

    PCRE2

https://github.com/PCRE2Project/pcre2

The PCRE2 lib implements regular expression pattern matching.

git clone --depth 1 https://github.com/PCRE2Project/pcre2
cd pcre2

./autogen.sh

cd ..
mkdir pcre2-build
cd pcre2-build

../pcre2/configure --prefix=/usr

make -j8

make install does not seem to work... Lets use mv on the lib dir.

sudo mv .libs/* /mnt/lib/

cd ..

OpenSSL

https://github.com/openssl/openssl

King Lib for SSL,TLS,HTTPS....

git clone --depth 1 https://github.com/openssl/openssl

mkdir openssl-build
cd openssl-build

../openssl/Configure --prefix=/usr

make -j8
sudo make DESTDIR="/mnt" install

cd ..

Update init V1

Now that we have the command to connect ourselves to the internet, we should add to our init to do it automatically.

sudo nano /mnt/sbin/init

This is the updated content:

#!/bin/bash

mount -t proc none /proc
mount -t sysfs none /sys

ip link set up eth0
ip addr add 10.0.2.15/24 dev eth0
ip route add 10.0.2.2 dev eth0
ip route add 0/0 via 10.0.2.2 dev eth0

exec /bin/bash

Lets talk about what we just did, we first enable eth0 which is our default network connector.

We set our IP to 10.0.2.15, the default with QEMU.

We create a route to our gateway 10.0.2.2, the default with QEMU.

Finally, we tell the system to route all traffic (0/0) via 10.0.2.2 connecting our LFN to the internet!

Important note QEMU uses SLIRP by default which very limited support for ICMP which is used for pings... TCP and UDP is fully supported.

MADE A MISTAKE WITH VIA

Third test

Lets Sync to test it!

sync
sync
sync

sudo umount /mnt
sudo losetup -d /dev/loop#
qemu-system-x86_64 disk.img

On LFN:

wget maplecircuit.dev
	Resolving maplecircuit.dev... failed: Temporary failure in name resolution.
	wget: unable to resolve host address 'maplecircuit.dev'

We can see here that we have an issue with name resolution, this should be fixed by adding a small DNS server.

Mount everything back up:

sudo losetup -fP --show disk.img
sudo mount /dev/loop#p1 /mnt

DNSMasq

DNSMasq is a small DNS server, it can be used for a bunch of other things and it was more widely used before systemd was the solution to everything (; .

git clone --depth 1 git://thekelleys.org.uk/dnsmasq.git
cd dnsmasq

make -j8

sudo mv src/dnsmasq /mnt/bin/

cd ..

Update init V2

Lets add DNSMasq to our init.

sudo nano /mnt/sbin/init

This is the updated content:

#!/bin/bash

mount -t proc none /proc
mount -t sysfs none /sys

ip link set up eth0
ip addr add 10.0.2.15/24 dev eth0
ip route add 10.0.2.2 dev eth0
ip route add 0/0 via 10.0.2.2 dev eth0

dnsmasq -uroot

exec /bin/bash

Lets Sync to test it!

sync
sync
sync

sudo umount /mnt
sudo losetup -d /dev/loop#
qemu-system-x86_64 disk.img

On LFN

dnsmasq: no user root

nano /etc/passwd

Content of the file

root:x:0:0:root:/root:/bin/bash

here is what it means:

  1. Username
  2. Password
  3. User ID
  4. Group ID
  5. User ID Info (comment)
  6. Home Directory
  7. Login Shell
  8. mkdir /root
    dnsmasq -uroot
    

On LFN

dnsmasq: failed to open pidfile /var/run/dnsmasq.pid: No such file or directory

We indeed, do not have a /var/run dir... lets fix that:

mkdir /var/run

While we are making files lets create /etc/resolv.conf

nano /etc/resolv.conf

Content of /etc/resolv.conf:

nameserver 1.1.1.1

Sync and restart LFN:

sync
#restart the LFN

lets try this:

wget maplecircuit.dev
	Unable to locally verify the issuers authority
wget maplecircuit.dev --no-check-certificate
nano index.html

It works!!!