ArchLinux DHCP配置问题

安装完ArchLinux后,发现网卡无法从路由器通过dhcp得到地址,ArchLinux的dhcp客户端是dhcpcd,默认配置文件。路由器型号是TP-link WR340G v5, 2010年入手的。

手动调用dhcpcd时候发现LOG里有NAK消息爆出。

翻了下Arch的论坛,这个问题是由于dhcpcd的参数配置引发的,某些dhcpcd向路由器请求的参数无法得到而导致,个人觉得大约是WR340G版本够老,无法提供这些个参数。

##解决方案一:

编辑/etc/dhcpcd.conf, 注释掉classless_static_routes 和 interface_mtu即可:

	# option classless_static_routes
	
	# Respect the network MTU.
	# option interface_mtu

而后我们可以用systemd在每次启动的时候自动调用dhcpcd绑定地址:

	$ systemctl enable dhcpcd@enp0s25
	$ systemctl start dhcpcd@enp0s25

##解决方案二:

安装dhclient:

	$ pacman -S dhclient
	$ dhclient enp0s25

这种方法需要每次手动输入,不过我们可以使用netctl包来自动管理网络接口信息:

	$ cp /etc/netctl/examples/ethernet-dhcp /etc/netctl/ethernet-dhcp

由netctl.profile查到指定dhcp客户端的字段,而后在/etc/netctl/ethernet-dhcp文件中添加:

	DHCPClient=dhclient
	# !!! 别忘了修改dhcp侦听的设备地址:
	# Interface=eth0
	Interface=enp0s25

把ethernet-dhcp作为netctl的默认启动配置文件:

	$ netctl enable ethernet-dhcp

立即开启netctl:

	$ netctl start ethernet-dhcp

查看netctl服务运行情况,我的网络是桥接的,和依据上面步骤配出来的字段会有所不同

	$ systemctl list-units -t service | grep netctl
	netctl@bridge.service        loaded active exited  Example Bridge connection

如果切换了网络环境,例如如果在待机唤醒时处于另一网络中,则需要用下列命令重新配置网络:

	$ netctl restart ethernet-dhcp

两种方法各有千秋,前者比较灵活,但是遇到复杂网络配置的时候可能会很棘手,譬如多网卡/桥接等模型时容易把人弄晕。后者配置选项很多,但一劳永逸。

Qemu快速上手

1. 安装Qemu

ArchLinux的仓库里包含有qemu已编译好的包:

	$ pacman -Ss qemu
	extra/qemu 1.4.2-2 [installed]
	    A generic and open source processor emulator which achieves a good \
	emulation speed by using dynamic translation.
	$ pacman -S qemu

会根据默认配置安装好几乎所有平台支持的Qemu.

或者你可以手动下载源码包进行编译:官方下载地址在http://wiki.qemu.org/Download

安装完qemu后运行qemu-system-i386, 如果弹出窗口,则说明qemu安装正确。

2. 创建新虚拟机磁盘镜像

创建虚拟机的第一步是创建一个新的磁盘镜像,qemu提供了对多种磁盘镜像格式的支持,如raw、qcow2、qed、vdi等,qemu-img的帮助里介绍qcow2是最多才多艺(Versatile)的格式,支持压缩、加密等功能,还能最大程度节省磁盘空间。我们选择它来做磁盘镜像(Virtualbox可以直接读取qcow2格式的虚拟机镜像)。

	$ qemu-img create -f qcow2 ubuntu.qcow2 16G
	Formatting 'ubuntu.qcow2', fmt=qcow2 size=17179869184 encryption=off \
	cluster_size=65536 lazy_refcounts=off 

3. 启动并安装虚拟机:

	$ qemu-system-i386 -hda ubuntu.qcow2 -boot d -cdrom \
	./ubuntu-13.04-desktop-i386.iso -m 1024 -enable-kvm

-boot d代表优先从光驱启动,对应的选项有a, b (软驱 1 和 2), c (硬盘优先), d (光盘优先), n-p(支持Etherboot的网卡1-4).

安装ubuntu的步骤很直观,这里就不用篇幅描述了。安装完毕后,使用下列命令启动安装好的虚拟机镜像

	$ qemu-system-i386 -hda ubuntu.qcow2 -m 1024 -enable-kvm

4. 配置虚拟机网络:

4.1 使用桥接网络

这种方法需要改动系统配置,使用bridge-utils来创建虚拟网卡和实际网卡之间的桥接。

	$ pacman -Ss bridge-utils
	core/bridge-utils 1.5-2
	    Utilities for configuring the Linux ethernet bridge
	$ pacman -S bridge-utils

创建桥接设备(br0)

	$ modprobe bridge
	$ brctl addbr br0

出现add bridge failed: Package not installed时的解决方法:

	$ brctl addbr br0
	add bridge failed: Package not installed
	# 查看kernel中关于bridge配置选项
	$ zcat /proc/config.gz | grep CONFIG_BRIDGE=
	CONFIG_BRIDGE=m
	# 查看是否存在ko文件
	$ ls /usr/lib/modules/`uname -r`/kernel/net/bridge
	bridge.ko.gz  netfilter
	# 加载bridge内核模块
	$ modprobe bridge
	# 检查内核模块是否被加载
	$ lsmod | grep ^bridge
	bridge                 93187  0 

若modprobe bridge后lsmod看不到bridge模块,有可能是因为更新完系统安装到新的kernel version后没有重启,ArchLinux是一个非常激进的发行版,内核往往几天一升级,习惯休眠或长期不关机的用户可能会碰到这个问题。

检查bridge网络

	$ brctl show br0
	bridge name	bridge id		STP enabled	interfaces
	br0		8000.000000000000	no

关于STP: Spanning Tree Protocol (STP) is a Layer 2 protocol that runs on bridges and switches. The specification for STP is IEEE 802.1D. The main purpose of STP is to ensure that you do not create loops when you have redundant paths in your network. Loops are deadly to a network. 生成树协议运行于bridge或交换机上,主要目的为确保在存在冗余路径时网络中不会生成回路,回路会造成网络的死循环。

用下列命令查看网口信息, 或者ifconfig -a直接查看也可:

	$ ifconfig -s | awk '{print $1}' | grep -v "Iface\|lo"
	enp0s25

将enp0s25加入到br0

	$ /sbin/ifconfig enp0s25 down
	$ /sbin/ifconfig enp0s25 0.0.0.0 promisc up
	$ brctl addif br0 enp0s25
	$ dhcpcd br0

查看bridge端口信息,发现enp0s25已经被加入了br0:

	$ brctl show br0
	bridge name	bridge id		STP enabled	interfaces
	br0		8000.c8cbb8b48913	no		enp0s25

有关bridge网络的dhcp相关配置,可以参考ArchLinux网络配置问题

创建qemu启动脚本:

	$ vim /etc/qemu-ifup
	#!/bin/sh
	  
	echo "Executing /etc/qemu-ifup"
	echo "Bringing up $1 for bridged mode..."
	sudo /usr/bin/ip link set $1 up promisc on
	echo "Adding $1 to br0..."
	sudo /usr/bin/brctl addif br0 $1
	sleep 2

更改脚本权限:

	$ chmod 750 /etc/qemu-ifup 
	$ chown -R root /etc/qemu-ifup 
	$ chgrp kvm /etc/qemu-ifup 

创建qemu结束脚本

	$ vim /etc/qemu-ifdown
	#!/bin/sh
	 
	echo "Executing /etc/qemu-ifdown"
	sudo /usr/bin/ip link set $1 down
	sudo /usr/bin/brctl delif br0 $1
	sudo /usr/bin/ip link delete dev $1

更改脚本权限:

	$ chmod 750 /etc/qemu-ifdown 
	$ chown -R root /etc/qemu-ifdown 
	$ chgrp kvm /etc/qemu-ifdown 

添加当前用户到kvm用户组并在visudo中开放对应命令的权限:

	$ usermod -a -G kvm Trusty
	$ visudo
	Cmnd_Alias      QEMU=/usr/bin/ip,/usr/bin/modprobe,/usr/bin/brctl
	%kvm     ALL=NOPASSWD: QEMU

建立run-qemu文件,并添加到系统路径中.

	$ vim /bin/run-qemu
	#!/bin/bash
	USERID=`whoami`
	precreationg=$(/usr/bin/ip tuntap list | /usr/bin/cut -d: -f1 | /usr/bin/sort)
	sudo /usr/bin/ip tuntap add user $USERID mode tap
	postcreation=$(/usr/bin/ip tuntap list | /usr/bin/cut -d: -f1 | /usr/bin/sort)
	IFACE=$(comm -13 <(echo "$precreationg") <(echo "$postcreation"))
	
	# This line creates a random mac address. The downside is the dhcp server will
	assign a different ip each time
	printf -v macaddr "52:54:%02x:%02x:%02x:%02x" $(( $RANDOM & 0xff)) $(( $RANDOM &
	0xff )) $(( $RANDOM & 0xff)) $(( $RANDOM & 0xff ))
	# Instead, uncomment and edit this line to set an static mac address. The
	benefit is that the dhcp server will assign the same ip.
	# macaddr='52:54:be:36:42:a9'
	  
	qemu-system-i386 -enable-kvm -net nic,macaddr=$macaddr -net tap,ifname="$IFACE"
	$*
	  
	sudo ip link set dev $IFACE down &> /dev/null
	sudo ip tuntap del $IFACE mode tap &> /dev/null 
	$ sudo chmod a+w /bin/run-qemu

使用下列命令来运行qemu

	$ /bin/run-qemu -hda ./ubuntu.qcow2 -m 1024 -vga std

运行多个run-qemu实例后的网络信息如下:

	$ ifconfig -s
	Iface      MTU    RX-OK RX-ERR RX-DRP RX-OVR    TX-OK TX-ERR TX-DRP TX-OVR Flg
	br0       1500    70676      0      0 0         64334      0      0      0 BMRU
	enp0s25   1500   103814      0      0 0         75661      0      0      0 BMPRU
	lo       65536      983      0      0 0           983      0      0      0 LRU
	tap0      1500        3      0      0 0            11      0      0      0 BMPRU
	tap1      1500        3      0      0 0            11      0      0      0 BMPRU

4.2 使用VDE(Virtual Distrubuted Ethernet)创建Qemu网络,这种方法无需改变系统配置。

有关VDE的配置可以参考前面写过的在CentOS上安装基于Qemu的虚拟机一文。

值得注意的是, vdeswitch和slirpvde都可以在ArchLinux的软件库中找到:

	$ pacman -Ss vde
	extra/vde2 2.3.2-4 [installed]
	    Virtual Distributed Ethernet for emulators like qemu

使用VDE创建的网络对外是不可见的,它使用由slirpvde分配的dhcp地址,通常以10.0.0开头,VDE配置的网络也可以在VirtualBox中看到,VirtualBox中关于NAT的网络配置就是基于VDE的。

ArchLinux上安装arm编译链

在X86_64的ArchLinux上安装Mentor Graphics提供的arm交叉编译链时出现下列问题:

	$ ./arm-2013.05-23-arm-none-eabi.bin 
	Checking for required programs: awk grep sed bzip2 gunzip
	===============================================================
	Error: Missing 32-bit libraries on 64-bit Linux host
	===============================================================
	Your 64-bit Linux host is missing the 32-bit libraries
	required to install and use Sourcery CodeBench.

解决方法:

编辑/etc/pacman.conf,去掉下列两行的注释

	[multilib]
	Include = /etc/pacman.d/mirrorlist

而后安装必要的ia32相关的包:

	$ pacman -Sy
	$ pacman -S lib32-glibc
	$ pacman -S lib32-gtk lib32-gtk2

安装好以后执行前面被中断的安装进程,这时候可以顺利安装了。

安装完毕后记得把交叉编译链的路径加入到系统路径中,最好在~/.bashrc里加上一笔:

	export PATH=$HOME/CodeSourcery/Sourcery_CodeBench_Lite_for_ARM_EABI/bin:$PATH
	export PATH=$HOME/CodeSourcery/Sourcery_CodeBench_Lite_for_ARM_GNU_Linux/bin:$PATH

ArchLinux的yaourt仓库里也有arm-none-eabi和arm-none-linux-eabi等交叉编译链,但是每次编译都会出现莫名其妙的错误,使用现成的编译链能大大节省开发时间。

ArchLinux初步配置网络

刚安装好的ArchLinux上只有基本的系统组件,启动以后连ifconfig都没有(其实ifconfig早在N年前就被干掉,以ip命令代替了)。在这种一穷二白的情况下,如何配置好网络参数?下面的步骤可以让人一劳永逸。

1. 查看网络接口信息:

	$ ip link show
	1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT 
	    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
	2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT qlen 1000
	    link/ether 08:00:27:09:fd:b7 brd ff:ff:ff:ff:ff:ff
可以看到enp0s3为有线端口,未启动,无地址无网关无路由。

2. 启动网口:

	$ ip link enp0s3 up

3. 配置网卡地址:

	$ ip addr add 192.168.1.133/24 broadcast 192.168.1.255 dev enp0s3

参数解释:IP地址: 192.168.1.133, 广播地址:192.168.1.255

4. 配置默认路由为192.168.1.1:

	$ ip default-gateway 192.168.1.1

5. 查看接口信息:

	#路由信息
	$ ip route show
	#地址信息
	$ ip addr show

6. 添加dns解析信息:

	$ vim /etc/resolv.conf

输入ISP提供的dns服务器信息,例如:

	nameserver 58.XXX.xx.xx
	nameserver 221.x.x.xx

7. 安装net-tools,这里包含了ifconfig,终于可以不用忍受ip命令的折磨了。但是我记得看过一个高手的文章,他建议使用ip而不是使用陈旧的功能有限的ifconfig,高手开了个玩笑:“记住每次你敲ifconfig时,就会有一只无辜的小猫咪因为偷吃奶酪被击杀,可怜可怜小猫咪吧 :(”。虽然ifconfig很方便也是大多数教程里的常用配置,还是建议大家尽快适应繁琐的ip命令。

	$ pacman -S net-tools

8. 安装dhcpcd并加入到系统启动项中:

	$ pacman -S dhcpcd
	# 临时启动dhcpcd
	$ systemctl start dhcpcd@enp0s3
	# 将dhcpcd加入到启动项中
	$ systemctl enable dhcpcd@enp0s3

现在重启机器,就可以从dhcp服务器自动获取地址并配置dns服务器等信息了。

9. 其他:

删除当前已经绑定的IP地址:

	$ ip addr del 192.168.1.134/32 dev enp0s3

若机器处于有防火墙的机器中,则需要配置好proxy信息才能正常使用网络,在命令行下,输入一下命令:

	$ export http_proxy=http://ip_address:ip_port
	$ export https_proxy=http://ip_address:ip_port
	$ export ftp_proxy=http://ip_address:ip_port
	$ export ftps_proxy=http://ip_address:ip_port

Linux忘记密码后使用grub重置密码

Linux忘记密码后,可以通过修改Grub启动参数来进行修复, 举Ubuntu13.04为例:

出现Grub菜单时,按"e"键或是其他键进入Grub的编辑方式。

menuentry 'Ubuntu' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-simple-baec278e-2b9f-4513-a6f1-e148ac6295d7' {
recordfail
	load_video
	gfxmode $linux_gfx_mode
	insmod gzio
	insmod part_msdos
	insmod ext2
	set root='hd0,msdos2'
	if [ x$feature_platform_search_hint = xy ]; then
	  search --no-floppy --fs-uuid --set=root --hint-bios=hd0,msdos2 --hint-efi=hd0,msdos2 --hint-baremetal=ahci0,msdos2  baec278e-2b9f-4513-a6f1-e148ac6295d7
	else
	  search --no-floppy --fs-uuid --set=root baec278e-2b9f-4513-a6f1-e148ac6295d7
	fi
	linux	/boot/vmlinuz-3.8.0-19-generic root=UUID=baec278e-2b9f-4513-a6f1-e148ac6295d7 ro   
	initrd	/boot/initrd.img-3.8.0-19-generic
}

改动下面这行

linux	/boot/vmlinuz-3.8.0-19-generic root=UUID=baec278e-2b9f-4513-a6f1-e148ac6295d7 ro   

linux	/boot/vmlinuz-3.8.0-19-generic root=UUID=baec278e-2b9f-4513-a6f1-e148ac6295d7 rw init=/bin/bash  

init=/bin/bash将把系统启动到一个没有root密码的shell, rw则允许修改密码,否则ro的情况下无法更新密码。

使用改动后的grub启动系统。在Grub2中一般是按F10, Grub中则是回车后按"b"键,具体需参考grub的帮助。

系统启动到shell后, 输入passwd username重设自己的密码后,reboot系统即可。