Last active
March 7, 2025 01:38
-
-
Save diyism/7857650 to your computer and use it in GitHub Desktop.
linux系统和应用目录都交错在一起了,用unionfs-fuse和pivot_root才能隔离,随系统启动:session-setup-script=session-setup-script.sh in /etc/lightdm/lightdm.conf @_:…boot+lib+(usr/)sbin+bin对SYS区,usr/(bin+lib+share)对APP区,etc+var公用
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
=================================pc lubuntu上, 2013年=========================================== | |
#!/bin/sh | |
#chroot only for root user session | |
#pivot_root for whole system root directory changing | |
#sudo su | |
#mkdir /mnt/new_root #must be 755 root:root, or else sudo won't work: unable to stat /etc/sudoers: Permission denied | |
#mkdir /mnt/root #must be 755 root:root | |
#mkdir /mnt/rw #must be 755 root:root | |
#mkdir /mnt/rw/old_root #mkdir /media/malcolm/ext2/old_root | |
#root, rw, new root | |
mount --bind / /mnt/root | |
mount /dev/sda2 /mnt/rw #mount --bind /media/malcolm/ext2 /mnt/rw | |
unionfs-fuse -o cow,allow_other,use_ino,suid,dev,statfs_omit_ro,max_files=32768,chroot=/mnt /rw=RW:/root=RO /mnt/new_root | |
#unionfs改用overlayfs性能更好(ofs>aufs>ufs): mount -t overlayfs overlayfs -o lowerdir=/mnt/root,upperdir=/mnt/rw /mnt/new_root | |
#很多特殊fs类型的目录需要bind到新root(可以用df -aT看到所有的): | |
mount --bind /proc /mnt/new_root/proc | |
mount --bind /sys /mnt/new_root/sys | |
mount --bind /dev /mnt/new_root/dev | |
mount --bind /dev/pts /mnt/new_root/dev/pts | |
mount --bind /run /mnt/new_root/run #for google chrome etc | |
mount --bind /run/shm /mnt/new_root/run/shm #for google chrome etc | |
mount --bind /run/lock /mnt/new_root/run/lock #for google chrome etc | |
mount --bind /run/user /mnt/new_root/run/user #for google chrome etc | |
mount --bind /tmp /mnt/new_root/tmp #for x socket in /tmp/.X11-unix, used by python etc. | |
ln -s /home/malcolm/.Xauthority /mnt/new_root/home/malcolm/.Xauthority #for x session in .Xauthority | |
#pivot_root | |
/sbin/pivot_root /mnt/new_root /mnt/new_root/old_root #the $PATH in session-setup-script lack "/sbin" | |
exit 0 #return success | |
#还需要清理过程: https://gist.github.com/diyism/7872699 | |
=================================pc kali上, 2018年=========================================== | |
kali usb boot有选项"Live USB Encrypted Persistence" 或 "Live USB Persistence"可以直接实现相对于base iamge的变化写到指定的磁盘 | |
=================================vps ubuntu上(digitalocean ubuntu 16.04 x64), 2018年========== | |
#ubuntu 14.04上没有overlayfs, ubuntu 18.04上的systemd-sysv没法用upstart-sysv替代掉, 而systemd无法在chroot(pivot_root)后使用, | |
#用不了switch_root, 因为switch_root后会导致目标overlay失效(别的overlay没影响), 看起来type是overlay实际已经退化到了/mnt/root | |
#switch_root /mnt/new_root /sbin/init | |
#还有个overlayroot的程序可以用另外一个分区作为overlay的upperdir, 但是不支持文件夹: | |
#http://blog.dustinkirkland.com/2012/08/introducing-overlayroot-overlayfs.html | |
#后述"4行代码超简类似docker容器"只能使用ubuntu 16.04的vps, 并且需要先执行命令: | |
#参考: http://without-systemd.org/wiki/index.php/How_to_remove_systemd_from_an_Ubuntu_Xenial_installation | |
apt-get install upstart-sysv -y | |
update-initramfs -u | |
#再到digitalocean网页switch off再switch on重启该vps后再ssh登录, 删除systemd: | |
apt-get remove --purge --auto-remove systemd #会删掉cgmanager,grub-pc-bin,liblxc1,libpam-systemd,lxc-common,lxd,policykit-1,snapd,systemd,systemd-shim,ubuntu-core-launcher | |
#给overlayfs及pivot_root准备挂载目录及脚本文件: | |
mkdir /mnt/rw #must be 755 root:root, or else sudo won't work: unable to stat /etc/sudoers: Permission denied | |
mkdir /mnt/rw/mnt && touch /mnt/rw/mnt/rw /mnt/rw/mnt/work /mnt/rw/mnt/new_root #阻止往从lowerdir继承来的4个空挂载点写入文件, 避免跟实际的下面两层layer混淆, 等pivot_root后实际的layer都在/old_root/mnt下 | |
mkdir /mnt/rw/old_root #mount overlay后会挂载到/mnt/new_root/old_root | |
mkdir /mnt/work #must be 755 root:root | |
mkdir /mnt/new_root #must be 755 root:root | |
#cp /etc/init.d/rc.local /etc/init.d/rc.boot | |
#sed -i 's/\$all//' /etc/init.d/rc.boot | |
#sed -i 's/rc.local/rc.boot/g' /etc/init.d/rc.boot #digitalocean ubuntu 16.04 vps里/etc/rc2.d下是S02ssh,S03rc.local | |
#不能用把S03rc.local改成S00rc.local的方法, 因为upstart-sysv在安装新service时会重命名S##rc.local为最大序号 | |
#ln -s ../init.d/rc.boot /etc/rc2.d/S01aaaarc.boot #抢在所有rc2.d之前执行overlay和pivot_root,比如抢在/etc/rc2.d/S02ssh之前,否则sshd进程还在旧root里 | |
#不能用上面4行, 因为mountall.conf触发filesystem事件后, /etc/init/rc-sysinit.conf触发runlevel事件, 再触发/etc/init/ssh.conf和/etc/init/rc.conf, | |
#如果加/etc/rc2.d/S01aaaarc.boot, 只是保证在/etc/init/rc.conf内第一个执行, 无法保证抢在/etc/init/内其他十几个"runlevel 2"进程前执行, 只能: | |
echo $'description "rc.boot"\nemits pivoted\nstart on filesystem\ntask\nexec /etc/rc.boot' >/etc/init/rc.boot.conf | |
sed -i 's/filesystem and/filesystem and pivoted and/' /etc/init/rc-sysinit.conf | |
#可以用date +%s.%N && echo $$打印纳秒时间及进程id 以及 initctl list|grep process 来观察各个服务的先后启动次序 | |
#注意上面的echo $'...\n...\n...'是bash命令, 后面用curl ...|sh执行时需要把那个"$"符号去掉 | |
#用overlayfs+pivot_root实现简单类似docker容器: | |
#参考: http://cmp.felk.cvut.cz/~pisa/linux/init-overlay | |
#用nano /etc/rc.boot编辑文件, 重启vps后变成/old_root/etc/rc.boot: | |
#!/bin/sh -e | |
exec 2> /tmp/rc.boot.log # send stderr from rc.boot to a log file | |
exec 1>&2 # send stdout to the same log file | |
set -x # tell sh to display commands before execution | |
#4行代码实现超简类似docker容器: | |
/bin/mount -n -t overlay overlay -o lowerdir=/,upperdir=/mnt/rw,workdir=/mnt/work /mnt/new_root #加"-n"避免写入/etc/mtab | |
#注意在merge层或upperdir改过文件后lowerdir的变动就再也影响不到上层了 | |
/bin/df -aT | /bin/grep -P -v "Type|ext4|overlay" | /usr/bin/awk '{print $7}' | /usr/bin/xargs -I {} /bin/mount --bind {} /mnt/new_root{} #pivot_root需要bind上旧的/proc, /sys, /dev, /run等等之后系统才能正常工作 | |
/usr/bin/unshare -m & #不要该行的话, pivot_root时会报错pivot_root: failed to change root from `/mnt/new_root' to `/mnt/work': Invalid argument, 可以用grep -iP '/ /\s' /proc/$$/mountinfo 看变化 | |
#不要该行的话, switch_root时会报错switch_root: failed to mount moving /dev to /mnt/new_root/dev: Invalid argument <\n> switch_root: forcing unmount of /dev | |
#另外需要结尾加"&"以及下行前加"sleep 2 &&", 否则/etc/rc.boot顶行的"-e"参数会退出 | |
sleep 2 && /sbin/pivot_root /mnt/new_root /mnt/new_root/old_root | |
/sbin/initctl emit pivoted | |
exit 0 | |
#然后: | |
chmod 755 /etc/rc.boot | |
#再到digitalocean网页switch off再switch on重启该vps后再ssh登录即可 | |
#完成 | |
===============最终简化为: 初始化digitalocean vps 16.04实现overlay容器:==================== | |
apt-get install upstart-sysv -y && update-initramfs -u | |
#再到digitalocean网页switch off再switch on重启该vps后再ssh登录执行: | |
curl -sSfL https://git.io/fNtyS | sh | |
#再到digitalocean网页switch off再switch on重启该vps后再ssh登录即可 | |
===============部署好nginx,php,mysql,业务代码等后, 备份rw层:==================== | |
#ssh进入vps, 再执行: | |
cd /old_root/mnt/rw | |
tar -czpf ../rw.ki7j.tar.gz * | |
#本地机器上执行: | |
scp -P 22 root@<vps ip>:/old_root/mnt/rw.ki7j.tar.gz ./ | |
===============在digitalocean或aws lightsail新建vps ubuntu 16.04并恢复rw层:==================== | |
#先ssh登录并执行(lightsail需要先sudo su): | |
apt-get install upstart-sysv -y && update-initramfs -u | |
#再到digitalocean/aws lightsail网页switch off再switch on重启该vps后再ssh登录执行: | |
curl -sSfL https://git.io/fNtyS | sh | |
#不重启vps, 到本地机器执行(先cd /doc/vps_bak/, 另外在中国可能需要前缀proxychains scp ..., 在aws lightsail需要scp -i private.key ...): | |
scp -P 22 ./rw.ki7j.tar.gz root@<new vps ip>:/mnt/ | |
#再到新vps里: | |
tar xzpf /mnt/rw.ki7j.tar.gz -C /mnt/rw/ | |
#再到digitalocean/aws lightsail网页switch off再switch on重启该vps后再ssh登录(有可能rw层已改过ssh端口和密码/密钥)即可 | |
#另外/old_root/etc/ssh/ssh_host_ecdsa_key.pub这个ssh客户端指纹等文件 是在pivot_root之前生成的base image层里, 没有备份到rw层, 导致恢复的新vps与旧vps略有差异 | |
========================在digitalocean上装13MB的bargeOS再执行一行命令就可以替代上述overlayfs+pivot_root的方法:========== | |
https://gist.github.com/diyism/60aa6ca24df772a4928f1aced65e72ee | |
docker run -it --privileged=true --net=host ubuntu /bin/bash | |
如果想在docker里启动多个服务, 并且bash里exit时不影响container继续运行: | |
docker run -dit --privileged=true --net=host ubuntu /bin/multirun cmd1 cmd2 ... | |
docker exec -it con_id_first_few_chars /bin/bash | |
运行x11 gui程序: | |
docker run -it -e DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix ubuntu cmd1 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment