使用Docker构建安全的虚拟空间

前期筹备

选择镜像:

空间应用的镜像为:mattrayner/lamp:latest-1604 (ubuntu 16.04 + apachd2 + mysql,着实只要有mysql-client 就可以了)

数据库所应用的镜像为: mysql:5 (mysql 官方镜像)

设置设置设备摆设摆设FTP:

和设置设置设备摆设摆设老例的 FTP 没什么差别,这里分外强调3点:

必然要开启 ch_root,防止不合用户之间可以相互查看文件;

假如应用被动模式,那么 云主机的安然组 或者iptables 不要忘了放行端口;

将 umask 设置为 022 (包管用户上传的文件默认权限为755

近来上的某水课的功课是出 ctf web题目,然而大年夜多半同砚连 php 都没学过,(滑稽)更别说设置设置设备摆设摆设办事器了,于是我想能不能趁机赚一波外快 造福一下同砚,(着实便是想折腾了)以是盘算把我自己的 vps 分成虚拟空间给大年夜家用然则一样平常的虚拟空间安然性难以获得包管,一个空间出问题,其他的用户可能都随着遭殃,也便是旁站进击更何况我们这个虚拟空间的用场是 ctf web 题目,总不能让人做出一道题目就能顺手拿到所有题目的 flag 吧于是想到了应用 docker 来构建安然的虚拟空间,其间碰到了不少问题,下面便是折腾的历程了

实现思路

大年夜体的思路是,在我的 vps 上为每个用户创建一个文件目录,然后将目录挂载到 docker 容器的默认网站目录,也便是/var/www/html,,用户可以经由过程 FTP 将网站源码上传到自己的文件目录,文件也会同步到容器内这样就实现了各个空间的情况隔离,避免旁站进击

而数据库则可以零丁构建一个 mysql 容器,为每个用户分配一个 user&database,让用户和空间容器来远程连接

选择一个位置寄放用户文件夹:

我这里新建一个 ~/rooms/ 来寄放用户的文件夹

设置设置设备摆设摆设数据库:

1. 收集:

要让虚拟空间的容器能够远程连接数据库,首先要使容器之间在一个网段,那么我们就必要设置一个桥接模式的 docker network,我这里应用 172.22.0.0/16 这个网段

$ docker network create –driver = bridge –subnet = 172 .22.0.0/16 room_net

2.创建 MySQL 容器:

我们的数据库必要满意:

容许用户远程连接;

容许空间容器连接

第一点要求,我们经由过程将数据库容器的 3306 端口映射到 VPS 的开放端口即可,我这里映射到 3307

第二点要求,只要经由过程我们刚刚设置的 docker network 即可实现

以是启动创建容器的敕令是的敕令是:

$ docker run -d –name room-mysql –network room_net –ip 172 .22.0.1 -p 3307 :3306 -e MYSQL_ROOT_PASSWORD = your_password mysql:5

值得留意的一点是,root 用户是不必要远程登录的,出于安然斟酌,我们应该 禁止其经由过程localhost意外的host登录

履行:

$ docker exec -it room-mysql /bin/bash -c “mysql -u root -p -e\”use mysql;update user set host=’localhost’ where user=’root’;drop user where user=’root’ and host=’%’;flush privileges;\””

创建空间历程

做好前期的筹备事情,我们就可以开始构建空间了,出于方便我们将全部历程编写成 shell 脚本,这样今后要新建空间的时刻,只必要运行一下就可以了

我们创建空间必要以下几个步骤:

1. 创建新的 FTP 用户

这个用户应该满意这样的要求:

可以上传文件到虚拟空间用户文件夹 (废话);

不能造访除虚拟空间用户文件夹之外的位置 (在设置设置设备摆设摆设 FTP 时经由过程ch_root 实现);

创建的时刻设置一个随机密码;

不能经由过程 ssh 登岸 (着实这也是用户能经由过程 ftp 连接 的必须前提假如不限定的话,ftp登录时会呈现 530 差错

那么对应的 shell 脚本便是:

#/home/ubuntu/rooms/ 即你的vps上用来寄放用户文件夹的位置# $1 参数为要设置的用户名,也是虚拟空间容器&数据库用户&数据库&用户文件夹的名字useradd -g ftp -d /home/ubuntu/rooms/$1 -m $1 ​pass=`cat /dev/urandom | head -n 10 | md5sum | head -c 10`#天生随即密码echo $1:$pass | chpasswd#为用户设置密码​#限定用户经由过程 ssh 登录(如/etc/shells 里没有/usr/sbin/nologin 必要自己加进去usermod -s /usr/sbin/nologin $1echo “create ftp user:$1 indentified by $pass”#输出用户名和密码

2. 新建数据库用户&数据库,并为用户赋权

这部分操作对照简单,我们就只必要为用户新建一个 MySQL 账户和一个专属数据库就好了

shell 脚本:

# 让用户输入 mysql 容器的 root 密码read -sp “请输入 MySQL 容器的 root 账户密码:” mysql_pass# 创建数据库docker exec -it mysql-docker /bin/bash -c “mysql -u root -p$mysql_pass -e \”create database $1;\””# 天生密码pass=`cat /dev/urandom | head -n 10 | md5sum | head -c 10`# 创建 MySQL 用户docker exec -it mysql-docker /bin/bash -c “mysql -u root -p$mysql_pass -e \”CREATE USER ‘$1’@’%’ IDENTIFIED BY ‘$pass’;\””# 为用户付与权限docker exec -it mysql-docker /bin/bash -c “mysql -u root -p$mysql_pass -e \”grant all privileges on $1.* to ‘$1’@’%’;flush privileges;\””# 输出账户信息echo “create database user:$1@’%’ indentified by $pass”

3. 新建空间

到现在我们已经可以创建空间容器了,想一想这个空间要满意什么基础要求呢?

能够外网造访;

能够连接数据库;

[1] [2]下一页

挂载用户文件夹内的文件到网站根目录

那么敕令便是:

$ docker run -d –name $1 –network room_net -p $2 :80 -v /home/ubuntu/rooms/$1 /www:/var/www/html mattrayner/lamp:latest-1604

然则作为一个用做虚拟空间的容器,我们还必要斟酌 内存 的问题,假如不加限定,docker默认应用的最大年夜内存便是 VPS 本身的内存,很轻易被人恶意耗尽主机资本

以是我们还要限定一下容器的最大年夜应用内存

关于 docker 容器内存应用的有趣的征象:

在最初,我把容器的内存限定到了 128m,然后造访网站发明 apache 办事没有正常启动,于是我把内存限定上调到了 256m,然后履行 docker stats 发明容器内存应用率靠近100%;

有趣的是,当我考试测验限定内存为 128m ,然背工动开启 apache 办事时,发明办事完全可以被正常启动,查看内存占用率,发明只占用了 30m 阁下的内存

为什么会呈现这种环境呢?我大年夜概猜想是由于容器内还有一些其他办事,当限定内存小于 256m 的时刻,这些办事无法被同时启用,然则我们可以只启用 apache 啊!

于是敕令变成了下面这样:

docker run -d –name $1 –cpus 0 .25 -m 64m –network room_net -p $2 :80 -v /home/ubuntu/rooms/$1 /www:/var/www/html mattrayner/lamp:latest-1604 docker exec -it $1 /bin/bash -c “service apach2 start;”

着末一步,改动挂载文件夹的所有者:

到这时,理论上我们的空间已经可以正常应用了,可是我用 FTP 连接上去发明,并没有权限上传文件

颠末漫长的 debug 后发明,在容器启动一段光阴后,我们挂载到容器内部的文件夹的所有者发生了改变,于是我查看了容器内部的 run.sh 脚本,发清楚明了这样的内容:

if [ -n “$VAGRANT_OSX_MODE” ];thenusermod -u $DOCKER_USER_ID www-datagroupmod -g $(($DOCKER_USER_GID + 10000)) $(getent group $DOCKER_USER_GID | cut -d: -f1)groupmod -g ${DOCKER_USER_GID} staffchmod -R 770 /var/lib/mysqlchmod -R 770 /var/run/mysqldchown -R www-data:staff /var/lib/mysqlchown -R www-data:staff /var/run/mysqldelse# Tweaks to give Apache/PHP write permissions to the appchown -R www-data:staff /var/wwwchown -R www-data:staff /appchown -R www-data:staff /var/lib/mysqlchown -R www-data:staff /var/run/mysqldchmod -R 770 /var/lib/mysqlchmod -R 770 /var/run/mysqldfi

可以看到,当没有设置 $VAGRANT_OSX_MODE 这个情况变量时,容器会改动 /app(/var/www/html 的软链接)文件夹的所有者为 www-data ,那么我们就必要在启动容器时,设置这个情况变量值为真

而 /app 文件夹 的默认所有者是 root 用户,我们将本地文件夹挂载到容器内的/app,后,本地文件夹的所有者也会变为 root 以是我们还必要改动本地文件夹的所有者

于是创建容器的 shell 脚本又变成了:

# 启动容器docker run -d –name $1 –cpus 0.25 -m 64m –network room_net -p $2:80 -eVAGRANT_OSX_MODE=1 -v /home/ubuntu/rooms/$1/www:/var/www/html mattrayner/lamp:latest-1604# 启动apache2docker exec -it $1 /bin/bash -c “service apache2 start;”# 改动挂载文件夹的所有者chown $1:ftp -R /home/ubuntu/rooms/$1/www

着末的脚本:

到现在创建空间的历程就停止了,那么贴上着末的脚本

创建空间脚本:

#!/bin/bash# The shell to create new room# Last modified by Li4n0 on 2018.9.25# Usage: #option 1: database/dbuser/room/ftpuser/ name#option 2: port​# create new ftp useruseradd -g ftp -d /home/ubuntu/rooms/$1 -m $1pass=`cat /dev/urandom | head -n 10 | md5sum | head -c 10`echo $1:$pass | chpasswdusermod -s /usr/sbin/nologin $1echo “create ftp user:$1 indentified by $pass”​# create new databaseread -sp “请输入 MySQL 容器的 root 账户密码:” mysql_passdocker exec -it mysql-docker /bin/bash -c “mysql -u root -p$mysql_pass -e \”create database $1;\””pass=`cat /dev/urandom | head -n 10 | md5sum | head -c 10`docker exec -it mysql-docker /bin/bash -c “mysql -u root -p$mysql_pass -e \”CREATE USER ‘$1’@’%’ IDENTIFIED BY ‘$pass’;\””docker exec -it mysql-docker /bin/bash -c “mysql -u root -p$mysql_pass -e \”grant all privileges on $1.* to ‘$1’@’%’;flush privileges;\””echo “create database user:$1@’%’ indentified by $pass”​#create new roomdocker run -d –name $1 –cpus 0.25 -m 64m –network room_net -p $2:80 -eVAGRANT_OSX_MODE=1 -v /home/ubuntu/rooms/$1/www:/var/www/html mattrayner/lamp:latest-1604docker exec -it $1 /bin/bash -c “service apache2 start;”chown $1:ftp -R /home/ubuntu/rooms/$1/www

删除空间脚本:

#!/bin/bashread -sp “请输入 MySQL 容器的 root 账户密码:” mysql_pass​#drop the databasedocker exec -it mysql-docker /bin/bash -c “mysql -u root -p$mysql_pass -e \”drop database $1\””​#delete dbuserdocker exec -it mysql-docker /bin/bash -c “mysql -u root -p$mysql_pass -e \”use mysql;drop user ‘$1’@’%’;flush privileges;\””​#delete the containerdocker stop $1docker rm $1​#delete ftp useruserdel $1rm -rf /home/ubuntu/rooms/$1

用法:

# 创建sudo create_room.sh room1 10080# 用户名 映射到 VPS 的端口# 删除sudo del_room.sh room1

总结

到这里我们就实现经由过程 docker 搭建较安然的虚拟空间了,当然,假如然的想上线运营,还有很多必要完善的地方,比如 空间大年夜小的限定、用户文件和数据库的准时备份等等,有兴趣的同伙可以去自己完善

那么到这里我的折腾就停止了,现在去卖空间给同砚发福利了!

上一页[1] [2]

赞(0) 打赏
分享到: 更多 (0)
免责申明:本站所有资料均来自于网络,版权归原创者所有!本站不提供任何保证,不保证真实性,并不承担任何法律责任

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

阿里云优惠网 更专业 更优惠

阿里云优惠券阿里云大礼包