Install ArchLinux insides Hyper-V
该文章根据 CC-BY-4.0 协议发表,转载请遵循该协议。
本文地址:https://fenying.net/en/post/2023/10/17/install-archlinux-in-hyper-v/
Overview
This is a tutorial to guide you to install ArchLinux inside Hyper-V on Windows 11 Pro, and solve the problems like:
- System-wide transparent proxy
- File sharing between guest and host
This guide is based on Windows 11 Pro English edition.
What’s the problem?
The biggest problems while installing ArchLinux inside Hyper-V are:
-
System-wide transparent proxy
Previously, we installed ArchLinux insides a VirtualBox machine, and it’s easy to configure proxy for the guest machines, by setting it to use NAT network, because NAT network is processed in process-level, which could be proxied by some system softwares like Proxifier.
However, it’s impossible to do the same thing in Hyper-V, even if you put your guest behind a NAT network,
The solution is to use
tun2socks
to redirect all the traffic to a proxy server. -
Sharing files between guest and host
In VirtualBox, it’s easy to share a folder between guest and host, by using VirtualBox’s system components. But in Hyper-V, you have to use
CIFS
to do that, and you have to solve the problem of Windows account password.
By the way, to improved the time of startup, we use UEFI boot mode.
Enabling Hyper-V
Download Archlinux LiveCD
Go to Archlinux Official Site, and choose a nearby mirror site, download the file archlinux-20**.**.**-x86_64.iso
.
Create Hyper-V Virtual Network
All operations below should use PowerShell with Administrator privilege.
-
Create an internal switch network
1New-VMSwitch -SwitchName "MyArchSwitch" -SwitchType Internal
If it’s successful, you will see:
1Name SwitchType NetAdapterInterfaceDescription 2---- ---------- ------------------------------ 3MyArchSwitch Internal
-
Open the system settings, choose “Network & Internet / Advanced network settings”
Find the network you are using, click to expand, and choose Edit in “More adapter options”.
TipsIt should be easier in Windows 10, you can find the traditional network management panel, right-click the network connection you are using, and choose "Properties" to open this UI.
In the new opened interface, switch to the Sharing tab, check the first checkbox “Allow other user connect through this computer’s internet connection”, and choose the Internal Switch you created above in the dropdown list, then click Save.
TipsDon't enable the second checkbox, because it will enable NAT, and we don't need it.
-
Run
Get-NetIPAddress -InterfaceAlias "vEthernet (MyArchSwitch)"
, you will see the IPv4 address of the host, it should be `TipsI choose `192.168.137.1/24` as the network segment.
-
Configure Windows Firewall rules, press
Win+S
, searchWindows Defender Firewall with Advanced Security
, in the opened console, chooseInbound Policy
in the left pane, then chooseNew Rule
in the right pane, and follow the steps:- Rule Type: Choose Custom, and click Next
- Program: Keep All Program, and click Next
- Protocol And Ports: Keep it, and click Next
- Scope: Add the local IP address
192.168.137.1·, and the remote IP address
192.168.173.2`, and click Next - Action: Keep it, and click Next
- Profile: Keep all three checked, and click Next
- Name: Give it a name, like “Allowed Archlinux in Hyper-V”, and click Finish
Create Hyper-V Virtual Machine
- Press
Win+S
, search and openHyper-V Manager
(Enable it if not found) - Click menu
Action / New / Virtual Machine
, to start the virtual machine creation wizard - Specify Name And Location: Set the name and storage path of the virtual machine
- Specify Generation: Choose Generation 2
- Assign Memory: At least 4GiB
- Configure Networking: Choose the Virtual Network Switch you created above, like
MyArchSwitch
- Connect Virtual Hard Disk: Choose to create a new virtual hard disk, and adjust the size, it should be no less than 40GiB
- Install Options: Choose “Install an operating system from a bootable CD/DVD-ROM”, and choose the Archlinux LiveCD file you downloaded before.
- Finish the creation, and continue to configure it.
Configure Hyper-V Virtual Machine
-
Find the virtual machine you created in Hyper-V Manager.
-
Right-click on it and choose
Settings
-
Go to the
Security
tab, and disableEnable Secure Boot
(You can enable TPM if needed) -
Go to the
Processor
tab, add 3 hard driver, with names:- Home: For
/home
, size as you need - Docker: For
/var/lib/docker
, size as you need - Swap: For swap partition, size as the same as the memory
- Add more if needed.
Remember, the order of the hard drivers should be: 0, 1, 2, 3. And the DVD Drive should be 4.
- Home: For
-
Go to the
Firmware
tab, make sureDVD Drive
is the first boot order, and moveNetwork Adapter
to the last. -
Go to the
Checkpoint
tab, disableEnable checkpoints
-
Click
Apply
, and then close
Install ArchLinux
-
Right-click the virtual machine, and choose
Connect
-
Click
Start
in the new opened window, and wait for the LiveCD to start -
Execute the command
ip addr
to check the IP address of the virtual machine, it should be192.168.137.xxx
, remember it. -
Execute
curl https://www.google.com
, to make sure the network is working -
Start the OpenSSH server by executing
systemctl start sshd
, so that you can connect to the virtual machine via SSH for further operations, which is convenient for copy-paste and so on. -
Execute
passwd
to set the password of theroot
user in the LiveCD system, so that you can connect to the virtual machine via SSH. -
Execute
ssh -p 22 [email protected]
to connect to the virtual machine via SSH, in your host machine. -
Initialize the disks:
1fdisk /dev/sda # Initialize the main disk 2 3o # Create a DOS partition table 4 5n # Create a partition 6p # Create a new primary partition 71 # The first partition 8Enter # Just press Enter 9+512M # Create a EFI partition 10 11n # Create a partition 12p # Create a new primary partition 132 # The second partition 14Enter # Just press Enter 15Enter # The rest of the disk 16 17w # Write the partition table and exit 18 19mkfs.fat /dev/sda1 # The EFI partition must be FAT format 20mkfs.ext4 /dev/sda2 # The root partition 21mkfs.ext4 /dev/sdb # The whole Home disk for `/home` 22mkfs.ext4 /dev/sdc # The whole Docker disk for `/var/lib/docker` 23mkswap /dev/sdd # The whole Swap disk for swap 24 25mount /dev/sda2 /mnt 26 27mkdir /mnt/boot 28mkdir /mnt/home 29mkdir /mnt/var/lib/docker -p 30 31mount /dev/sda1 /mnt/boot 32mount /dev/sdb /mnt/home 33mount /dev/sdc /mnt/var/lib/docker 34 35swapon /dev/sdd
-
Configure Pacman mirror (Optional)
Edit the file
/etc/pacman.d/mirrorlist
withvim
, and add your preferred mirror at the top:Usually unnecessary, because the default mirror is fast enough.
However, if you are in some region with network control, you may need to setup a custom mirror to speed up the download.
-
Start the installation
1pacstrap /mnt base linux linux-firmware dhcpcd openssh vim wget sudo unzip
2
3genfstab -U /mnt >> /mnt/etc/fstab
4arch-chroot /mnt
- Initialize the system
1ln -sf /usr/share/zoneinfo/America/New_York /etc/localtime # Set the timezone
2echo 'MyXXXXX' > /etc/hostname # Set the hostname
3hwclock --systohc # Set the hardware clock
4
5ln -s /usr/bin/vim /usr/bin/vi
6
7vi /etc/locale.gen # Uncomment line of en_US.UTF-8 UTF-8
8
9locale-gen # Generate the locale
10echo 'LANG=en_US.UTF-8' > vi /etc/locale.conf # Set the locale
11
12passwd # Set the password for root
- Create a normal user
1systemctl enable sshd # Enable SSH server and make it start on boot
2
3YOUR_USER=xxxxx # Set the username
4useradd -m $YOUR_USER # Create a normal user (the UID and GID will be 1000 by default)
5
6visudo # Uncomment line of %sudo ALL=(ALL:ALL) ALL
7groupadd sudo
8
9usermod -aG sudo $YOUR_USER # Add the normal user to the sudo group
10passwd $YOUR_USER # Set the password for the normal user
11
12mkdir /home/$YOUR_USER/.ssh
13echo 'YOUR-SSH-Pubkey' > /home/$YOUR_USER/.ssh/authorized_keys # Set the SSH public key for the normal user
14chmod 0700 /home/$YOUR_USER/.ssh
15chmod 0600 /home/$YOUR_USER/.ssh/authorized_keys
16chown -R $YOUR_USER:$YOUR_USER /home/$YOUR_USER/.ssh
-
Configure the network
This solution will set a fixed IP for easy access, here we use
192.168.137.2/32
1pacman -S dhcpcd 2systemctl enable dhcpcd 3 4echo 'interface eth0' >> /etc/dhcpcd.conf 5echo 'static ip_address=192.168.137.2/24' >> /etc/dhcpcd.conf 6echo 'static routers=192.168.137.1' >> /etc/dhcpcd.conf
By the way, you can also set a fixed DNS server, like using Cloudflare’s DNS:
However if you wanna enable DoT/DoH, please skip this configuration.
1echo 'static domain_name_servers=1.1.1.1' >> /etc/dhcpcd.conf
-
DoH/DoT (Optional)
1pacman -S dnscrypt-proxy 2systemctl enable dnscrypt-proxy 3echo 'static domain_name_servers=127.0.0.1' >> /etc/dhcpcd.conf
Edit
/etc/dnscrypt-proxy/dnscrypt-proxy.toml
, uncomment line ofserver_names = [...]
, and add your preferred DoH/DoT server, like:TipsIf your network does not allow access these DoT/DoH servers, you can use a proxy server to access them. ```toml proxy = 'socks5://192.168.137.1:11111' # Your proxy server ```
-
Setup EFI
1exit # Go back to the LiveCD 2 3blkid /dev/sda2 # Find and copy the content of PARTUUID="xxxxxxxx-xx" 4 5efibootmgr \ 6 --disk /dev/sda \ 7 --part 1 \ 8 --create \ 9 --label "Linux Kernel" \ 10 --loader /vmlinuz-linux \ 11 --verbose \ 12 --unicode 'root=PARTUUID=xxxxxxxx-xx rw initrd=\initramfs-linux.img' # Replace xxxxxxxx-xx with the PARTUUID you copied 13 14poweroff # Shutdown, and then start again, you will enter the system.
Appendixes
Automatically start ssh-agent
when the user logs in
This must be run as a normal user, not as root, because the
ssh-agent
must be separated for each user.
1mkdir -p ~/.config/systemd/user/
2
3cat > ~/.config/systemd/user/ssh-agent.service <<EOF
4[Unit]
5Description=SSH key agent
6
7[Service]
8Type=simple
9Environment=SSH_AUTH_SOCK=%h/.config/ssh-agent.socket
10ExecStart=/usr/bin/ssh-agent -D -a \$SSH_AUTH_SOCK
11
12[Install]
13WantedBy=default.target
14EOF
15
16echo 'export SSH_AUTH_SOCK=~/.config/ssh-agent.socket' >> ~/.bashrc
17
18systemctl --user enable --now ssh-agent.service # Login again to make it work
Remember the SSH keys in ssh-agent
Only works with
ssh-agent
.
When a SSH key is used in ssh/scp commands, you may want to remember it in ssh-agent
, avoiding
retype the password every time.
Prepend the following lines to ~/.ssh/config
:
1AddKeysToAgent yes
Optimize the effect of Ctrl key in the command line
Must be executed as root.
Edit the file /etc/inputrc
, add two lines in the middle:
1"\C-h": backward-kill-word
2"\e[3;5~": kill-word
Now you can use Ctrl + Delete
and Ctrl + Backspace
to delete nearby words.
Take effect after you restart the terminal.
Switch to LTS version of Linux kernel
Must be executed as root.
If you prefer use a stable version of Linux kernel, you can switch to LTS version.
1pacman -S linux-lts efibootmgr
2
3blkid /dev/sda2 # Find and copy the content of PARTUUID="xxxxxxxx-xx"
4
5efibootmgr \
6 --disk /dev/sda \
7 --part 1 \
8 --create \
9 --label "Linux Kernel LTS" \
10 --loader /vmlinuz-linux-lts \
11 --verbose \
12 --unicode 'root=PARTUUID=xxxxxxxx-xx rw initrd=\initramfs-linux-lts.img' # Replace xxxxxxxx-xx with the PARTUUID you copied
13
14poweroff # Shutdown, and then start again, you will enter the system using LTS kernel.
If it works well, you can remove the old kernel:
1pacman -R linux
Enable access to host directories by CIFS
Must be executed as root.
-
Create a normal user in Windows
Go to Windows system settings, create a normal user (like
arch-guest
), set the password login (do not set reset password and password expiration). -
Right-click on the directory you want to share (like
D:/VMShared
), choose “Properties”, go to “Sharing”, choose “Advanced Sharing”, go to “Permissions”. -
Remove all permissions of “Everyone”, then click “Add”, add the user you created, grant all permissions, and save.
-
Go to your virtual machine, execute the following command:
1pacman -S cifs 2 3mkdir /mnt/vmshared # where to mount the shared directory in the guest machine 4 5id $YOUR_USER # Check the UID and GID of the normal user 6 7echo 'username=xxxxxxxxxxxx' > ~/.windows_credentials # The username in Windows 8echo 'password=xxxxxxxxxxxx' >> ~/.windows_credentials # The password in Windows 9 10mount -t cifs \ 11//HOST-PC-NAME/VMShared \ 12/mnt/vmshared \ 13-o credentials=/root/.windows_credentials,ip=192.168.137.1,iocharset=utf8,file_mode=0600,dir_mode=0700,uid=1000,gid=1000 14 15ls /mnt/vmshared # Check if the shared directory is mounted successfully, or check dmesg for errors 16 17echo '//HOST-PC-NAME/VMShared /mnt/vmshared cifs credentials=/root/.windows_credentials,ip=192.168.137.1,iocharset=utf8,file_mode=0600,dir_mode=0700,uid=1000,gid=1000,x-systemd.automount 0 0' >> /etc/fstab # Set it to mount automatically on boot
Setup system-wide transparent proxy (Optional)
Must be executed as root.
Download the latest stable version of tun2socks
in https://github.com/xjasonlyu/tun2socks/releases/.
And you should replace the version v2.5.1
with the new version you downloaded.
Don’t forget change the line
proxy: socks5://192.168.137.1:11111
to your proxy server.
1sudo su # Switch to root
2cd ~
3
4wget https://github.com/xjasonlyu/tun2socks/releases/download/v2.5.1/tun2socks-linux-amd64-v3.zip
5unzip tun2socks-linux-amd64-v3.zip
6rm tun2socks-linux-amd64-v3.zip
7mkdir /usr/local/tun2socks/bin -p
8mv tun2socks-linux-amd64-v3 /usr/local/tun2socks/bin/tun2socks
9
10cat > /usr/local/tun2socks/bin/init.sh <<EOF
11#!/usr/bin/env bash
12ip tuntap add mode tun dev tun0
13ip addr add 10.0.0.1/16 dev tun0
14ip link set dev tun0 up
15ip route add default via 10.0.0.1 dev tun0 metric 1
16EOF
17
18chmod 0700 /usr/local/tun2socks/bin/*
19
20cat > /usr/local/tun2socks/config.yml <<EOF
21# debug / info / warning / error / silent
22loglevel: warning
23
24# URL format: [protocol://]host[:port]
25proxy: socks5://192.168.137.1:11111
26
27# URL format: [driver://]name
28device: tun://tun0
29
30# Maximum transmission unit for each packet
31mtu: 1500
32
33# Network interface to bind, Linux/macOS only
34interface: eth0
35
36# Timeout for each UDP session, default value: 60 seconds
37udp-timeout: 60s
38
39# SO_MARK socket option, Linux only
40fwmark: 0
41EOF
42
43cat > /usr/lib/systemd/system/tun2socks.service <<EOF
44[Unit]
45Description=Tun2socks
46Documentation=https://github.com/xjasonlyu/tun2socks
47After=network.target network-online.target
48
49[Service]
50Type=simple
51ExecStart=/usr/local/tun2socks/bin/tun2socks -config /usr/local/tun2socks/config.yml
52Restart=always
53
54[Install]
55WantedBy=multi-user.target
56EOF
57
58cat > /usr/lib/systemd/system/init-tun2socks.service <<EOF
59[Unit]
60Description=Init Tun2socks
61Documentation=https://github.com/xjasonlyu/tun2socks
62After=network.target network-online.target
63
64[Service]
65Type=simple
66ExecStart=/usr/local/tun2socks/bin/init.sh
67
68[Install]
69WantedBy=multi-user.target
70EOF
71
72systemctl enable --now init-tun2socks.service
73systemctl enable --now tun2socks.service
Map ports to host (Optional)
The guest machine is behind the NAT network, so you will need to map the ports to the host.
The netsh
command can be used to achieve port mapping. Here is how to use it, and don’t forget to execute it in an administrator PowerShell terminal:
-
Add a port mapping
To map port 22 of the guest machine to port 2222 of the host machine, execute the following command:
1netsh interface portproxy add v4tov4 listenport=2222 listenaddress=0.0.0.0 connectport=22 connectaddress=192.168.137.2
-
Check the existing port mappings
1netsh interface portproxy show all
An example output:
1Listen on ipv4: Connect to ipv4: 2 3Address Port Address Port 4--------------- ---------- --------------- ---------- 50.0.0.0 2222 192.168.137.2 22
-
Delete a port mapping
Delete a port mapping by executing the following command:
1netsh interface portproxy delete v4tov4 listenport=2222 listenaddress=0.0.0.0
FAQ
What if network is not working after reboot?
-
If tun2socks is enabled, please check if the proxy server is working.
-
If the network of host machine is changed, please turn off sharing of previous NIC, and share the current NIC to the virtual switch.