FTP
2.5.2实现基于MYSQL验证的vsftpd虚拟用户
利用pam-mysql模块可以实现基于MySQL的FTP虚拟用户功能(ftp调用pam,pam跟mysql进行交互)
项目网站:
http://pam-mysql .sourceforge.net/
https://sourceforge.net/projects/pam-mysql/
http://sf.net/projects/pam-mysql
注意:因为此项目年代久远不再更新,当前只支持Centos 6,7,不支持Centos 8
2.5.2.1在数据库服务器上安装mysq数据库
注意: MySQL8.0由于取消了PASSWORD()函数不支持,因此选择Mariadb
[root@centos8 ~]
[root@centos8 ~]
数据库进行安装初始化
mysql_secure_installation
当前root密码
设置root密码
删除匿名用户
运行root用户远程登陆 是
删除测试数据库并访问它 否
现在重新加载特权表 是
2.5.2.2在数据库服务上配置数据库支持vsftpd服务
建立存储虚拟用户数据库和表(创建表,要把两个字段写好,user 和passwd)
[root@centos8 ~ ]#mysql
mysql> CREATE DATABASE vsftpd;
mysql> USE vsftpd;
mysgl> CREATE TABLE users (
id INT AUTO_INCREMENT NOT NULL PRIMARY KEY,
name CHAR (50 ) BINARY NOT NULL ,
password CHAR (41 ) BINARY NOT NULL
);
添加虚拟用户,为了安全应该使用PASSWORD函数加密其密码后存储(两个密码最好不一样)
mysgl> INSERT INTO users(name, password)values ('ftp_wang' , password('magedu' ));
mysgl> INSERT INTO users(name, password)values ('ftp_mage' , password('magedu' ));
mysql> select * from users;
创建连接的数据库用户
mysql> GRANT SELECT ON vsftpd.* To vsftpd@'10.0.0.%' IDENTIFIED BY '123456' ;
mysql> FLUSH PRIVILEGES;
2.5.2.3在FTP服务器上安装vsftpd和pam-mysq包
2.5.2.4在FTP服务器上安装pam_mysql
对于centos 6: pam_mysql由EPEL的源中提供epel
安装pam_mysql
[root@centos6 ~]
对于centos7和8:无对应rpm包,需手动编译安装
注意:当前版本的源码不支持CentOS 8,使用中会提示下面错误
[root@centos8 ~]
Jan 2 10:20:31 centos8 vsftpd[15519]: PAM unable to
dlopen(/usr/1ib64/security/pammysql .so): /usr/1ib64/security/pam_mysq1.so:
undefined symbol: make_scrambled_password
pam-mysq源码进行编译
安装相关包
「root@centos7 ~]
下载pam-mysql源码进行编译
「root@centos7 ~]
https://github.com/Nigelcunningham/pam-MysQL/archive/vo.8.1.tar.gz
「root@centos7 ~1
[root@centos7 ~]
[root@centos7 pam_mysq1-0.7RC1]
如果上面命令不指定--with-pam-mods-dir=/1ib64/security 会报以下错误
checking if the second argument of pam_conv.conv() takes const pointer... no
configure: error: Your system doesn't appear to be confiqured to use PAM
Perhaps you need to specify the correct location where the PAM modules reside.
[root@centos7 pam_mysql-0.7RC1] #make && make install
[root@centos7 pam_mysq1-0.7RC1]#ll /lib64/security/pam_mysql*
-rwxr-xr-x 1 root root 882 Dec 17 14:34 /1ib64/security/pam_mysq1.1a
-rwxr-xr-x 1 root root 141712 Dec 17 14:34 /1ib64/security/pam_mysql.so
2.5.2.5在FTP服务器上建立pam认证所需文件(创建一个文件)
[root@centos7 ~]
auth required pam_mysql.so user=vsftpd passwd=magedu host=172.26.112.62(mysqlserver) db=vsftpd table=users usercolumn=name passwdcolumn=password crypt=2
account required pam_mysql.so user=vsftpd passwd=magedu host=172.26.112.62(mysqlserver) db=vsftpd table=users usercolumn=name passwdcolumn=password crypt=2
注意:以上参考README文档
crypt加密方式:
0表示不加密
1表示crypt(3)加密
2表示使用mysql password)函数加密
3表示md5加密
4表示sha1加密
配置字段说明
auth表示认证
account验证账号密码正常使用
required表示认证要通过
pam_mysql.so模块是默认的相对路径,是相对/ib64/security/路径而言,也可以写绝对路径;后面为给此模块传递的参数
user=vsftpd为登录mysql的用户
passwd=magedu登录mysql的的密码
host=mysalserver mysq服务器的主机名或ip地址
db=vsftpd指定连接msyq的数据库名称
table=users 指定连接数据库中的表名
usercolumn=name当做用户名的字段
passwdcolumn=password当做用户名字段的密码
crypt=2密码的加密方式为mysql password()函数加密
2.5.2.6建立相应用户和修改vsftpd配置文件
建立虚拟用户映射的系统用户及对应的目录
[root@centos7 ~]
centos7需除去ftp根目录的写权限(需要上次的文件需要提前存在到upload目录下,只对这个目录有权限,无法在put 别的目录比如/etc/hosts)
[root@centos7 ~]
[root@centos7 ~]
确保/etc/vsftpd/vsftpd.conf中已经启用了以下选项
[root@centos7 ~]
添加下面两项
guest_enable=YES
guest_username=vuser
pam_service_name=vsftpd.mysql
启动vsftpd服务
[root@centos7 ~]
关闭selinux和防火墙,(注意:都关)
setenforce 0
systemctl stop firewalld
登陆ftp测试(在ftproot目录下创建ftproot.txt文件)
[root@localhost ~]
[root@localhost ftproot]
登陆
[root@localhost ~]
Connected to 172.26.122.116 (172.26.122.116).
220 (vsFTPd 3.0.2)
Name (172.26.122.116:root): li
331 Please specify the password.
Password:
230 Login successful. (登陆成功)
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> pwd
257 "/"
ftp> ls (可以看到/data/ftproot/下的目录和文件)
227 Entering Passive Mode (172,26,122,116,98,217).
150 Here comes the directory listing.
-rw-r--r-- 1 0 0 0 Mar 11 03:23 ftproot.txt
drwxrwxr-x 2 0 0 6 Mar 11 02:50 upload
226 Directory send OK.
ftp> cd upload
ftp> put /etc/hosts (但是无法上传,下面2.5.2.7方法设置不同用户的文件权限不一样,其中一个拥有上传权限)
local : /etc/hosts remote: /etc/hosts
227 Entering Passive Mode (172,26,122,116,104,48).
550 Permission denied.
2.5.2.7在FTP服务器上配置虚拟用户具有不同的访问权限
vsftpd可以在配置文件目录中为每个用户提供单独的配置文件以定义其ftp服务访问权限,每个虚拟用户的配置文件名同虚拟用户的用户名.配置文件目录可以是任意未使用目录,只需要在vsftpd.conf指定其路径及名称即可
配置vsftpd为虚拟用户使用配置文件目录
root@centos7 ~]
添加如下选项(这个目录就是让我们每一个人都有自己的配置文件)
user_config_dir=/etc/vsftpd/conf.d/
创建所需要目录,并为虚拟用户提供配置文件
Troot@centos7 -
配置虚拟用户的访问权限
虚拟用户对vsftpd服务的访问权限是通过匿名用户的相关指令进行的.如要让用户wang具有上传文件的权限,可修改/etc/vsftpd/vusers.d/wang文件,在里面添加如下选项并设置为YES即可,只读则设为NO
注意:需确保对应的映射用户对于文件系统有写权限
[root@centos7 ~1
anon_upload_enable={YES|NO}
anon_mkdir_write_enable={YES | NO}
anon_other_write_enable={YES | NO}
重新启动服务,验证一下
systemctl restart vsftpd
Name (172.26.122.116:root): li
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> pwd
257 "/"
ftp> ls
227 Entering Passive Mode (172,26,122,116,132,90).
150 Here comes the directory listing.
-rw-r--r-- 1 0 0 0 Mar 11 03:23 ftproot.txt
drwxrwxr-x 2 0 0 6 Mar 11 02:50 upload
226 Directory send OK.
ftp> cd upload
250 Directory successfully changed.
ftp> put (只能上传此目录下的文件)
anaconda-ks.cfg .bashrc .mysql_history .tcshrc
.bash_logout .cshrc pam_mysql-0.7RC1/
.bash_profile ftproot.txt pam_mysql-0.7RC1.tar.gz
ftp> put ftproot.txt (上传成功)
local : ftproot.txt remote: ftproot.txt
227 Entering Passive Mode (172,26,122,116,136,170).
150 Ok to send data.
226 Transfer complete.
虚拟用户登录有的目录改变至指定的目录(/data/ftproot2此目录需要提前创建,或者之后创建后重新登陆ftp)
local_root=/data/ftproot2
NFS服务
3.1 NFS工作原理(就是让你访问远程文件时如同访问本地文件,就是挂载)
NFS: Network File System网络文件系统,基于内核的文件系统.Sun公司开发,通过使用NFS,用户和程序可以像访问本地文件一样访问远端系统上的文件,基于RPC (Remote Procedure Call Protocol 远程过程调用)实现RPC 采用C /S 模式,客户机请求程序调用进程发送一个有进程参数的调用信息到服务进程,然后等待应答信息.在服务器端,进程保持睡眠状态直到调用信息到达为止.当一个调用信息到达,服务器获得进程参数,计算结果,发送答复信息,然后等待下一个调用信息,最后,客户端调用进程接收答复信息,获得进程结果,然后调用执行继续进行
对于linux 而言,文件系统一般是在内核中实现,指的是平常使用的单机文件系统,分布式文件系统在用户级实现也是有的,传统意义上文件系统都是在内核中实现,nfs 的核心实现也是在内核中实现的。
nfs 实现的效果是本地对本地文件系统接口的调用却被映射到网络中的另外一个主机上来了,这就是一种远程过程调用的概念叫做rpc ,一般来讲我们的文件系统既然是在内核中实现的,也就意味着我在硬件之上的内核上实现了多个系统调用,这些系统调用就叫做systemc ,当用户空间的应用程序在运行时,如果需要执行某些特权操作时,发送给工作在内核中的哪个所谓的某个子功能,这些调用我们称作叫本地系统调用。
函数也过程的区别在于,函数有返回值,而过程没有
rpc :远程函数调用(调用远程主机上的函数,结果也是远程主机返回的)
一部分功能由本地程序完成
另一部分功能由远程主机上的函数完成
rpc 服务:是有portmapper 程序提供可以通过rpcinfo 工具查看,portmappe 自己监听在某个固定的tpc /udp111 端口上,他提供了很多进程随时等待请求
NFS 优势: 节省本地存储空间,将常用的数据如: /home目录,存放在NFS服务器上且可以通过网络访问,本地终端将可减少自身存储空间的使用
3.2 NFS软件介绍
软件包: nfs-utils (包括服务器和客户端相关工具(c/s架构需要都安装软件包), CentOS8最小化安装时默认没有安装,nfs安全性不是很严谨,一般在企业内部使用)
安装:
centos7
yum -y install nfs-utils
ubuntu((nfs客户端和服务端都需要安装,server是所有的包,客户端安装一个common就可以了))
服务端:apt -y install nfs-server
客户端:apt -y install nfs-common
启动服务:systemctl enable --now nfs-server
相关软件包: rpcbind (必须) , tcp_wrappers
Kernel支持: nfs.ko
端口: 2049(nfsd),其它端口由portmap(111)分配(端口是半随机的,每次启动都会不一样)
NFS服务主要进程:
rpc.nfsd 最主要的NFS进程,管理客户端是否可登录
rpc.mountd挂载和卸载NFS文件系统,包括权限管理
rpc.lockd非必要,管理文件锁,避免同时写出错(两个用户同时打开一个文件,例如两个vim打开同一个文件,会冲突,为了避免对文件进行加锁,当一个人打开时,别人不能打开)
rpc.statd非必要,检查文件一致性,可修复文件
说明: Centos 6开始portmap进程由rpcbind代替
日志: var/lib/nfs/
NFS配置文件:
/etc/exports(主要配置文件,配置文件比较简单,每一行表示一个nfs文件系统,每一行共享一个。需要共享的文件,默认是这个文件)
/etc/exports.d/*.exports(尽量使用这种子配置文件,共享多个不同的文件,不用的使用不同的文件,避免使用同一个文件)
注意,需要共享文件夹的写权限,或者读权限,使用chmod 添加权限,可以使用777,宿主,宿组在linux上起作用的是id 而不是宿主,宿组,root用户权限太大,创建的文件会修改名字和id ,普通用户无所谓。centos7和centos8的映射的用户名不同,no_root_squash此选项可以不修改root的id 和名字,默认就是这个
3.3 NFS共享配置文件格式
/dir 主机1(opt1,opt2) 主机2(opt1,opt2) ...
(共享文件名,指定目录是什么或者文件系统)(第一个主机客户端他的访问选项是什么。比如ro,或root_squash,*表示全部主机)
格式说明:
以
主机格式:
anonymous:表示使用*通配所有客户端
单个主机: ipv4, ipv6, FQDN
IP networks:两种掩码格式均支持
172.18.0.0/255.255.0.0
172.18.0.0/16
wildcards:主机名通配,例如: *.magedu.com, IP不可以
netgroups: NIS域的主机组, @group_name
每个条目指定目录导出到的哪些主机,及相关的权限和选项
默认选项: (ro, sync , root_squash, no_al1-squash)
ro,rw 只读和读写(共享方式ro只读,不能修改,rw读写,可以读,可以写,但是给这个权限还不够,还需要文件系统的这个文件写权限)
async 异步,数据变化后不立即写磁盘,先写入到缓冲区中,过一段时间再写入磁盘,性能高,安全性低(异步存储到内存种。效率高,存储到内存中快,不安全)
sync (1.0.0版本后为默认,之前为异步)同步,数据在请求时立即写入共享存储磁盘,性能低,安全性高(同步直接存储到磁盘中,持久存储,安全)
用户映射
root_squash (默认,我们称作叫挤压root用户)远程root映射为nfsnobody, UID为65534, centos8为nobody,Centos7以前的版本为nfsnobody
no_root_squash 远程root映射成NFS服务器的root用户
all_squash 所有远程用户(包括root)都变成nfsnobody, centos8为nobody
no_all_squash (默认)保留共享文件的UID和GID
anonuid和anongid 指明匿名用户映射为特定用户UID和组GID,而非nobody,可配合all-squash使用(使用方式anonuid=80,anongid=80用逗号隔开,无论什么用户和组都修改为80id,使用场景同一个用户使用同一个id ,或者全部的访问用户都映射为特定用户UID和组GID)
范例: NFS配置示例
vim /etc/exports
/myshare server.example.com
/myshare *.example.com
/myshare server?.example.com
/myshare server[0-20].example.com
/myshare 172.25.11.10
/myshare 172.25.0.0/16
/myshare 2000:472:18:b51:c32:a21
/myshare 2000:472:18:b51::/64
/myshare .example.com 172.25.0.0/16
/myshare desktop. example. com(ro)
/myshare desktop.example.com(ro) server [0-20] .example.com(rw)
/myshare diskless.example.com(rw, no_root_squash)
3.4 NFS工具
3.4.1 rpcinfo
rpcinfo工具可以查看RPC相关信息
查看注册在指定主机的RPC程序(hostname是主机地址,nfs一般不变在互联网上使用,因为它的端口太多了,一般是在企业内部使用)
rpcinfo -p hostname
查看RPC注册程序
rpcinfo -s hostname
范例: rpcinfo
[root@centos8 ~]
[root@centos8 ~]
[root@centos7 ~]
[root@centos7 ~]
3.4.2 exportfs(避免重启服务,使用这种方式,-r重新加载文件)
exportfs:可用于管理NFS导出的文件系统
常见选项:
-V
-r
-a
-au
示例:
[root@localhost ~]
/shared/nfs 172.26.122.116(sync ,wdelay,hide,no_subtree_check,sec=sys,ro,secure,root_squash,no_all_squash)
/var/ftp 172.26.112.62(sync ,wdelay,hide,no_subtree_check,sec=sys,rw,secure,root_squash,no_all_squash)
3.4.3 showmount
常见用法:
查看远程主机的NFS共享
showmount -e hostname
范例:
[root@centos7 ~]
Export list for 10.0.0.8:
/data/wordpress *
3.4.4 mount.nfs
客户端NFS挂载(客户端可以看到远程共享的文件,要想使用需要挂载到本地文件系统中,注意:客户端挂载也需要nfs-utils程序包)
NFS相关的挂载选项: man 5 nfs
fg
bg
hard
soft
intr
rsize
_netdev
vers
提示: 基于安全考虑,建议使用nosuid,_netdev, noexec挂载选项
范例: 临时挂载NFS共享
mount -o rw,nosuid,fg,hard,intr 172.16 .0.1 :/testdir /mnt/nfs/
范例
[root@centos7 ~]
[root@centos7 ~]
[root@centos7 ~]
index.htm
[root@centos7 ~]
Filesystem Type 1K-blocks Used Available Use% Mounted on
10.0 .0.8 :/data/wordpress nfs4 52403200 398336 52004864 1 % /mnt/nfs
范例: 开机挂载
vim /etc/fstab
172.16 .0.1 :/public /mnt/nfs nfs defaults,_netdev 0 0
(远程路径地址和文件名) (挂载到的本地路径) (文件系统) (权限或选项)注意:网络挂载会有网络访问不到的问题,可能会造成系统启动不起来,或者产生等待时间,可以修改自动挂载的选项比如为_netdev无网络连接不挂载
范例: 远程的root映射为NFS服务器的nobody用户
[root@centos6 ~]
nobody: x: 99 : 99 :Nobody :/ :/sbin/nol ogin
nfsnobody: x: 65534 : 65534 : Anonymous NFS User: /var/lib/nfs: /sbin/nologin
[root@centos7 ~]
nobody: x: 99 : 99 :Nobody :/ :/sbin/nol ogin
nfsnobody: x: 65534 : 655 34 : Anonymous NFS User: /var/lib/nfs: /sbin/nologin
[root@centos8 ~]
nobody: x: 65534 : 65534 : kernel overflow user: /:/sbin/nologin
3.5自动挂载
可使用autofs服务按需要挂载外围设备, NFS共享等,并在空闲5分钟后后自动卸载
3.5.1相关包和文件
软件包: autofs(需要安装并启动,实现所谓的开机自动挂载,访问文件时挂载)
安装:[root@localhost ~]
服务文件: /usr/i b/systemd/system /autofs.service(这个服务要启动起来)
启动服务:[root@localhost ~]
配置文件: /etc/au to.master(挂载关系,有这个配置文件定义)
3.5.2配置文件格式
参看帮助: man 5 autofs
所有导出到网络中的NFS启用特殊匹配-host至"browse"
范例: /net目录可以自动挂载NFS共享
cat /etc/auto.master
/net -hosts
cd /net/192.168.8.100/
自动挂载资源有两种格式:
相对路径法:将mount point路径分成dirname 和basename 分别配置,可能会影响现有的目录结构,(在/etc/auto.master中写的是dirname ,他说我这里有一个文件夹要挂载,但是具体是那个子文件夹要挂载就不管我的事了,有另外一个子配置文件定义,这个子配置文件在/etc/auto.master文件中自己定义,创建)
绝对路径法:直接匹配全部的绝对路径名称,都写入到指定的配置文件里不会影响本地目录结构
3.5.2.1相对路径法(缺点会干扰我们现有的文件夹,文件夹内的原有数据不存在,覆盖掉了,解决方案绝对路径法)
1, /etc/auto.master格式
挂载点的dirname 指定目录的配置文件路径,如:/etc/test.auto(真正记录挂载目录,需要创建)
2,指定目录的配置文件格式
/etc/test.auto
挂载点的basename 挂载选项 挂载的设备
范例:相对路径法
[root@centos8 ~]
(misc表示父文件夹dirname ,misc下的子文件)(/etc/auto.miso表示子配置文件信息文件路径,里面写了子配置文件信息)
misc /etc/auto.miso
[root@centos8 ~
cd -fstype-iso9660,ro,nosuid,nodev:/dev/cdrom
(挂什么?/dev/cdrom挂光盘,-fstype-iso9660,ro,nosuid,nodev选项)
范例:相对路径法为支持通配符
vim /etc/auto.master
/misc /etc/auto.miso
vim /etc/auto.misc
表示/misc下面的子目录和nfs共享/export目录的子目录同名
* server:/export/&
3.5.2.2绝对路径法(把所有的路径放在一个文件中不在区分了,都放在一个配置文件中,修改了主配置文件,需要重新服务)
1. /etc/auto.master格式
/- 指定配置文件路径(文件名和路径自己取)
(/-为固定格式,表示绝对路径法)(后面跟上子配置文件路径,子配置文件放在哪都行)
子配置文件中将/mnt/nfs所有路径都写上
/mnt/nfs -fstype=nfs 172.26.122.116:/shared/nfs
2,指定配置文件格式
挂载点完整的绝对路径 挂载选项 挂载的设备
/mnt/nfs -fstype=nfs 172.26.122.116:/shared/nfs
范例:绝对路径法
vim /etc/auto.master:
/- /etc/auto.direct
(/-为固定格式)
vim /etc/auto.direct:
/foo -fstype=nfs server1:/export/foo
/user/local/ -fstype=nfs, vers=3 server1:/usr/local
/mnt/cdrom -fstype-iso9660 :/dev/cdrom
3.7实战案例
(创建/data/home目录将这个目录共享出去,让别人能够访问到)
[root@localhost ~]
(编辑/etc/下的exports)
[root@localhost ~]
(共享目录名) (供谁访问,这就是认证,后面要明确说明只允许那些客户端访问,比如运行172.26.119.40访问)(访问权限是什么?ro只读?还是rw读写?,如果有多个选项彼此之间用逗号隔开)(主机之间用空白分割)
/shared/nfs *(rw)
(重新加载服务)
[root@localhost ~]
(关闭防火墙,如果不关闭远程主机无法showmount查看)
[root@localhost ~]
(如果知道这个能不能被访问到,可以使用showmount,使用-e选项,指明这台主机,就能查看这台主机上共享的文件系统,和共享给那些主机访问)(这个命令可以远程查看,只要指明nfs服务的地址,前提需要安装yum -y install showmount)
[root@localhost ~]
Export list for 172.26.122.116:
/shared/nfs 172.26.122.116,172.26.119.40
(挂载NFS文件系统,注意挂载前需要确定主机上安装了nfs-utils否则会报错)
(mount -t nfs SERVER:/path/to/sharedfs /pash/to/mount_point)
(mount -t nfs)(指明你挂载服务器哪台主机ip:/路径)(挂载到本地所指定的位置)
mount -t nfs 172.26.122.116:/shared/nfs /mnt
(验证一下,在172.26.122.116本地nfs服务器主机上复制一个文件,到/shared/nfs目录下)
[root@localhost ~]
[root@localhost ~]
issue
(在远程主机上查看挂载目录下是否存在文件,可以看到没有问题)
[root@localhost ~]
issue
(远程主机上添加文件,可以看到无法复制,也就是不能在这个目录下操作,这就是默认的root_squash选项,挤压root用户,如果是root用户来访问到本地上就变成nfsnobody,而nfsnobody机会没有任何权限,只有读和执行权限,也就意味着可以看,但是不可以写)
[root@localhost ~]
cp : 无法创建普通文件"/mnt/inittab" : 权限不够
(服务器主机给共享文件文件系统的最大权限,放开控制)
[root@localhost ~]
(远程主机可以在挂载点下创建文件了,但是用户名root被映射为最小权限的nfsnobody用户)
[root@localhost nfs]
[root@localhost nfs]
总用量 0
-rw-r--r--. 1 nfsnobody nfsnobody 0 3月 11 17:59 1.txt
(不挤压root用户no_root_squash,拥有完整的root用户权限,让管理员用它自己的身份来访问)
vi /etc/exports
/shared/nfs 172.26.119.40(no_root_squash,rw) 172.26.122.116(ro)
(重载服务)
systemctl restart nfs
(远程主机在复制文件,可以看到复制成功,而且属组,属主是root)
[root@localhost ~]
[root@localhost ~]
总用量 8
-rw-r--r--. 1 root root 511 3月 11 15:06 inittab
-rw-r--r--. 1 root root 23 3月 11 14:43 issue
(切换个用户试试,服务器端创建用户,并使gentoo有访问权限 (失败,没有引入777权限测试,暂时不用))
[root@localhost ~]
[root@localhost ~]
(su到gentoo在/shared/nfs目录下创建文件)
[root@localhost ~]
[gentoo@localhost ~]$ cd /shared/nfs/
[gentoo@localhost nfs]$ ls
inittab issue
[gentoo@localhost nfs]$ touch a.gentoo
[gentoo@localhost nfs]$ ls -l
总用量 8
-rw-rw-r--. 1 gentoo gentoo 0 3月 11 15:11 a.gentoo
-rw-r--r--. 1 root root 511 3月 11 15:06 inittab
-rw-r--r--. 1 root root 23 3月 11 14:43 issue
(在远程主机上创建用户,切换用户,并查看,可以看到两个文件都是fedora,我们给了gentoo写权限但是没有给fedora写权限,但是依然可以创建原因就是uid一样,所以这个fedora在访问主机的时候被当成gentoo了,而gentoo恰好有写权限,所以他正好能写了)
[root@localhost ~]
[root@localhost ~]
[fedora@localhost ~]$ cd /mnt
[fedora@localhost mnt]$ touch a.fedora
[fedora@localhost mnt]$ ll
总用量 8
-rw-rw-r--. 1 fedora fedora 0 3月 11 15:58 a.fedora
-rw-rw-r--. 1 fedora fedora 0 3月 11 15:56 a.gentoo
-rw-r--r--. 1 root root 511 3月 11 15:51 inittab
-rw-r--r--. 1 root root 23 3月 11 15:50 issue
(远程主机创建一个gentoo用户,测试一下id 不是600(随机给的id ),用户名相同,但是id 不同。就不能写了,他只用id 号来识别用户)
[root@localhost ~]
[root@localhost ~]
uid=1000(gentoo) gid=1001(gentoo) 组=1001(gentoo)
[root@localhost ~]
[gentoo@localhost ~]$ cd /mnt
[gentoo@localhost mnt]$ ll
总用量 8
-rw-rw-r--. 1 fedora fedora 0 3月 11 15:58 a.fedora
-rw-rw-r--. 1 fedora fedora 0 3月 11 15:56 a.gentoo
-rw-r--r--. 1 root root 511 3月 11 15:51 inittab
-rw-r--r--. 1 root root 23 3月 11 15:50 issue
[gentoo@localhost mnt]$ touch b.gentoo
touch : 无法创建"b.gentoo" : 权限不够
(不用关闭nfs服务,即可实现文件系统的重新导出,编辑配置文件添加一条共享)
[root@localhost ~]
[root@localhost ~]
/shared/nfs 172.26.119.40(no_root_squash,rw) 172.26.122.116(ro)
/var/ftp 172.26.112.62(rw)
(可以看到没有重启nfs服务,没有导出)
[root@localhost ~]
Export list for 172.26.122.116:
/shared/nfs 172.26.122.116,172.26.119.40
(使用exportfs -ar重新导出所有的文件系统,不用重启服务,维护exports文件导出的文件系统表的专用工具。exportfs -au关闭导出的所有文件系统。exportfs -u FS 指明fs也可以只关闭一个,关闭指定的导出的文件系统)
Export list for 172.26.122.116:
/var/ftp 172.26.112.62
/shared/nfs 172.26.122.116,172.26.119.40
(远程主机,开机自动挂载nfs文件系统,添加挂载选项_netdev)
[root@localhost ~]
172.26.122.116:/shared/nfs nfs defaults,_netdev 0 0
(mount查看,挂载选项重点关注的rsize=131072,wsize=131072,timeo=600。rsize的值是从服务器读取的字节数, wsize是写入到服务器的字节数,默认都是1024, 如果使用比较高的值,如8192,可以提高传输速度)
(远程主机,使用autofs实现自动挂载,需要提前安装并启动)
[root@localhost ~]
mkdir : 已创建目录 "/shared"
mkdir : 已创建目录 "/shared/nfs"
[root@localhost ~]
mkdir : 已创建目录 "/data"
mkdir : 已创建目录 "/data/home"
[root@localhost ~]
[root@localhost ~]
[root@localhost ~]
/shared/nfs *(rw) 172.26.122.116(ro)
/data/home *(rw)
[root@localhost ~]
[root@localhost ~]
Export list for 172.26.122.116:
/data/home *
/shared/nfs (everyone)
[root@localhost ~]
[root@localhost ~]
(我们想把共享文件夹172.26.122.116:/shared/nfs挂载到/misc/nfs,怎么实现?很简单我们吧/misc和nfs拆开,写到不同的配置文件中)
(auto.master文件写/misc,这表示这个/misc这里的所有挂载他都不管了,以后有/etc/auto.misc说的算)
[root@localhost ~]
/misc /etc/auto.misc (相对路径法)
/- /etc/auto.home (绝对路径法,修改了主配置文件,需要重新服务)
(修改/etc/auto.misc文件,添加字段,挂载名nfs这是个文件夹,文件系统类型-fstype=nfs是nfs,挂载的文件是172.26.122.116:/shared/nfs)
[root@localhost ~]
nfs -fstype=nfs 172.26.122.116:/shared/nfs (相对路径法)
[root@localhost ~]
/home/nfs -fstype=nfs 172.26.122.116:/data/home (绝对路径法,修改了主配置文件,需要重新服务)
(文件默认是不挂载的,只有在切换到nfs目录下的时候挂载)
[root@localhost misc]
[root@localhost misc]
[root@localhost nfs]
[root@localhost nfs]
文件系统 1K-块 已用 可用 已用% 挂载点
/dev/mapper/centos-root 52403200 1017608 51385592 2% /
devtmpfs 464440 0 464440 0% /dev
tmpfs 475296 0 475296 0% /dev/shm
tmpfs 475296 12292 463004 3% /run
tmpfs 475296 0 475296 0% /sys/fs/cgroup
/dev/sda1 1038336 127044 911292 13% /boot
/dev/mapper/centos-home 77548548 32992 77515556 1% /home
tmpfs 95060 0 95060 0% /run/user/0
172.26.122.116:/shared/nfs 52403200 1071872 51331328 3% /misc/nfs
3.7.1目标
将NFS的共享目录,通过autofs发布出来,做为远程主机用户的家目录(将server的home目录成为客户端端home目录)(autofs文件包需要安装,并启动服务)
3.7.2环境准备
共三台主机
一台主机nfs server
IP:10.0.0.8
另两台当nfs client
IP:10.0.0.7
IP:10.0.0.6
3.7.3步骤
NFS服务器创建用户和相应的家目录,将用户wang的家目录共享
[root@centos8 ~]
[root@centos8 ~]
[root@centos8 ~]
/data/home *(rw)
[root@centos8 ~]
[root@centos8 ~]
在第一台NFS客户端主机10.0.0.7上实现相对路径法的autofs
[root@centos7 ~]
[root@centos7 ~]
/home /etc/auto.home
[root@centos7 ~]
* -fstype=nfs,vers=3 10.0.0.8:/data/home/&
[root@centos7 ~]
[root@centos7 ~]
Last login: Fri Jul 3 16:33:34 CST 2020 on pts/0
[user1@centos7 ~]$pwd
/home/userl
[userl@centos7~]$df /home/user1 -T
Filesystem Type 1K-blocks used Available use% Mounted on
10.0.0.8:/data/home/user1 nfs4 52403200 398464 52004736 1% /home/userl
[root@centos7 ~]
userl
[root@centos6 -]
[root@centos6 -]
/- /etc/auto.home
[root@centos6 -]
/home/user1 -fstype=nfs,vers=3 nfsserver:/data/home/userl
[root@centos6 -]
[root@centos6 -]
[user1@centos6 ~]$pwd
/home/userl
[user1@centos6 ~]sdf -T /home/user1
Filesystem Type 1K-blocks Used Available Use% Mounted on
10.0.0.8:/data/home/userl nfs 52403200 398464 52004736 1% /home/user1
[user1@centos6 ~]$ls /home
mage user1 wang
samba
4.1 SAMBA服务简介
SMB: Server Message Block服务器消息块, IBM发布,最早是DOS网络文件共享协议,是私有协议
CIFS: common internet file system,微软基于SMB发布
SAMBA: 1991年Andrew Tridgell,实现windows和UNIX相通
官方网站: http://www.samba.orgl
SAMBA的功能:
共享文件和打印,实现在线编辑
实现登录SAMBA用户的身份认证
可以进行NetBIOS名称解析
外围设备共享
Windowsit算机网络管理模式:
作组WORKGROUP:计算机对等关系,帐号信息各自管理
域DOMAIN: C/s结构,帐号信息集中管理, DC,AD
4.2 SAMBA软件介绍
相关包:
samba提供smb服务器端
samba-client户端软件
samba-common通用软件
cifs-utils smb客户端工具
samba-winbind 和AD相关
相关服务进程:
smbd提供smb (cifs)服务TCP:139,445
nmbd NetBIOS名称解析UDP:137,138
主配置文件: /etc/samba/smb.conf帮助参看: man smb.conf
语法检查: testparm [V] [/etc/samba/smb.conf
客户端工具: smbclient, mount.cifs
范例:
nmb是通过域名访问的服务,如果只是使用ip地址访问,不启动nmb服务也可以
dnf install samba
systemctl start smb
systemctl start nmb
4.3 SAMBA客户端工具
UNC路径: Universal Naming Convention,通用命名规范,格式如下
\\sambaserver\sharename
4.3.1使用smbclient访问SAMBA服务器
mbclient -L instructor.example.com
smbclient -L instructor.example.com -U smb用户%password
smbclient //instructor.example.com/shared -U wang
>cd directory
>get filel
>put file2
4.3.2挂载CIFS文件系统
范例:手动挂载
mount -o user-wang, password-magedu //server//sharec /mnt/smb
范例:开机自动挂载
cat /etc/fstab
//server/homes /mnt cifs credentials或cred=/etc/smb.txt oo
cat /etc/smb.txt
username-wang
password=password
chmod 600 /etc/smb.txt
范例: SMB协议版本
[root@centos8 ~]
4.4管理SAMBA用户
4.4.1实现samba用户说明
包: samba-common-tools
工具: smbpasswd pdbedit
用户数据库: /var/ lib/samba/private /passdb.tdb
说明: samba用户须是Linux 用户,建议使用/sbin/nologin
4.4.2管理用户命令
添加samba用户:
smbpasswd -a <user>
pdbedit -a -u <user>
修改用户密码:
smbpasswd <user>
删除用户和密码:
smbpasswd -x <user>
pdbedit -x -u <user>
查看samba用户列表:
pdbedit -L -v
范例:创建samba用户
注意不要用-r设为系统用户,因为不会生成家目录
[root@centos8 ~]
[root@centos8 ~]
root@centos8 ~]
root@centos8 ~]
[root@centos8 ~]
[root@centos8 ~]
[root@centos8 ~]
[root@centos8 ~]
查看samba服务器状态:
smbstatus
范例:
[root@centos8 ~]
4.5 SAMBA服务器配置
samba配置文件/etc/samba/smb.conf格式,使用.ini文件的格式
帮助: man smb.conf
用[]分成以下几部分
全局设置:
[global]服务器通用或全局设置的部分
特定共享设置:
[homes] 用户的家目录共享
[printers] 定义打印机资源和服务
[sharename] 自定X的共享目录配置
其中:
samba配置中的宏定义:
%m客户端主机的NetBIOS名
%M客户端主机的FQDN
%H当前用户家目录路径
%U当前用户的用户名
%g当前用户所属组
%h samba服务器的主机名
%L samba服务器的NetBIOS名
%I客户端主机的IP,是i的大写字母
%T当前日期和时间
%S可登录的用户名
4.5.1 SAMBA服务器全局配置
workgroup指定工作组名称
server string主机注释信息
netbios name指定NetBIOS名,可以被SAMBA客户端使用,但不支持ping
注意: netbios name需要启动nmb服务
范例:
[global]
workgroup = workgroup
netbios name = smbserver
interfaces指定服务侦听接口和IP
hosts allow可用逗号,空格,或tab分隔,默认允许所有主机访问,也可在每个共享独立配置,如在[globalj设置,将应用并覆盖所有共享设置,可以是以下格式:
IPv4 network/prefix: 172.16.0.0/24 IPV4前缀: 172.16.0.
IPv4 network/netmask: 172.16.0.0/255.255.255.0
主机名: desktop.example.com
以example.com后缀的主机名: .example.com
范例:
hosts allow = 172.16. .example. com
hosts deny拒绝指定主机访问,格式和hosts allow相同
config file=/etc/samba/conf.d/%U用户独立的配置文件
Log file=/var/log/samba/log.%l不同客户机采用不同日志
log level=2日志级别,默认为0,不记录日志
范例:
[global]
Log file=/var/1og/samba/log.%I
log level = 2
max log size=50日志文件达到50K,将轮循rotate,单位KB
Security三种认证方式:
user: samba用户(采有linux用户, samba的独立口令)
share:匿名(CentOS7不再支持),已不建议使用
server:已不建议使用
passdb backend = tdbsam密码数据库格式
4.5.2配置特定目录共享
每个共享目录应该有独立的[]部分
[共享名称]
comment
path
publid
browsable
writable=yes
read only=no
write list
写,不在列表中用户只读
valid users
范例:基于特定用户和组的共享
vim /etc/samba/smb. conf
[share]
path =/data/dir
valid users =wang,@admins
writeable = no
browseable = no
4.6实战案例
4.6.1实战案例:利用SAMBA实现指定目录共享
在samba服务器上安装samba包
yum -y install samba
groupadd -r admins
useradd -s /sbin/nologin -G admins wang
smbpasswd -a wang
useradd -s /sbin/nologin mage
smbpasswd -a mage
创建samba共享目录,并设置SElinux
mkdir /testdir/smbshare
chgrp admins /testdir/smbshare
chmod 2775 /testdir/smbshare
samba服务器配置
vim /etc/samba/smb.conf
...省略...
[share]
path = /testdir/smbshare
write list = @admins
systemctl enable --now smb nmb
samba客户端访问
yum -y instal1 cifs-utils
用wang用户挂载smb共享并访问
mkdir /mnt/wang
mount -o username-wang //smbserver/share /mnt/wang
echo "Hello wang" >/mnt/wang/wangfile.txt
用mage用户挂载smb共享并访问
mkdir /mnt/mage
mount -o username=mage //smbserver/share /mnt/mage
touch /mnt/mage/magefile.txt
4.6.2实战案例2:实现不同samba用户访问相同的samba共享,实现不同的配置
创建三个samba用户,并指定密码为magedu
useradd -s /sbin/nologin smbl
useradd -s /sbin/nologin smb2
useradd -s /sbin/nologin smb3
smbpasswd -a smbl
smbpasswd -a smb2
smbpasswd -a smb3
修改samba配置文件
vim /etc/samba/smb.conf
在workgroup下加一行
config file= /etc/samba/conf.d/%u
[share]
Path=/data/dir
Read only= NO
Guest ok = yes
write list=@wheel
vim /etc/samba/conf.d/smb1
[share]
Path=/data/dir1
Read only=No 等价于writable = yes
create mask=0644
vim /etc/samba/conf.d/smb2
[share]
path=/data/dir2
systemctl restart smb nmb
smbclient //sambaserver/share -U smb1%magedu
smbclient //sambaserver/share -U smb2%magedu
smbclient //sambaserver/share -U smb 3%magedu
数据的实时同步
在生产环境,有时会需要两台主机的特定目录实现实时同步.比如,将NFS共享目录的数据文件,自动实时同步到备份服务器特定目录中
5.1实时同步技术介绍
实现实时同步的方法
inotify +rsync方式实现数据同步
sersync:前金山公司周洋(花椒直播)在inotify软件基础上进行开发的,功能更加强大
工作原理:
要利用监控服务(inotify) ,监控同步数据服务器目录中信息的变化
发现目录中数据产生变化,就利用rsync服务推送到备份服务器上
inotify:
异步的文件系统事件监控机制,利用事件驱动机制,而无须通过诸如cron等的轮询机制来获取事件,linux内核从2.6.13起支持inotify,通过inotify可以监控文件系统中添加、删除,修改、移动等各种事件
可以看到内核里面是否支持inotify,可以看到CONFIG_INOTIFY_USER=y这是有inotify的功能模块的,在内核里面有这个功能
[root@localhost ~]
CONFIG_INOTIFY_USER=y
实现inotify软件:
inotify-tools
sersync
rsyncd
inotify+rsync使用方式
inotify对同步数据目录信息的监控
rsync完成对数据的同步
利用脚本进行结合
5.1.1 实现文件备份服务
实现周期性的备份:
做计划任务,但是如何拉过来呢?跨网络协议怎么走,我们使用rsync就可以,rsync可以实现增量型的数据传输,没变化的数据可以不传,有变化的数据传过来就行了
示例:
[root@centos8mini ~]
[root@localhost ~]
[root@centos8mini ~]
[root@centos8mini ~]
[root@localhost ~]
root@172.26.119.40's password:
[root@localhost ~]# ls /data/wordpress-backup/
fstab hosts
# 执行验证,并推过去
[root@localhost ~]# ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:VXdz4SXY9za6RsxZwVmib4kHrh7rMvyAJYmDk6V7oec root@localhost.localdomain
The key' s randomart image is:
+---[RSA 2048]----+
| .o=oO|
| ..ooB=|
| . . o oo|
| = . . . . + +o|
| = + o S = O..|
| + o + . O |
| o o ... o . . |
| + +o o o |
| E == . |
+----[SHA256]-----+
[root@localhost ~]
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@172.26.119.40's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh ' 172.26.119.40'"
and check to make sure that only the key(s) you wanted were added.
# 这时候再去同步,是不是密码不用输了,是不是把这个命令以后用计划任务执行一下就行了
[root@localhost ~]# rsync -a 172.26.119.40:/data/wordpress/ /data/wordpress-backup
# 计划任务crontab选项-e然后吧命令写到计划任务里,比如说我们半夜两点半格式,30 半夜2点 * * *这是不是每天晚上的半夜两点半(30 2 * * * )。我们为了看效果,这样我们(* * * * *)每分钟执行一次,这样看效果更快
[root@localhost ~]# which rsync
/usr/bin/rsync
[root@localhost ~]# crontab -e
* * * * * /usr/bin/rsync -a 172.26.119.40:/data/wordpress/ /data/wordpress-backup
# 我们做好计划任务以后,我们就观察一下/data/wordpress-backup,我们故意的用watch命令-n0.5 ls -l看一下这个文件,目前来讲这里面有fatab和hosts这两个文件,我们观察一下时间,在nfs服务端创建一个文件
[root@localhost ~]# watch -n0.5 ls -l /data/wordpress-backup
Every 0.5s: ls -l /data/wordpress-backup Thu Mar 11 22:16:50 2021
总用量 8
-rw-r--r--. 1 root root 541 3月 11 21:58 fstab
-rw-r--r--. 1 root root 158 3月 11 21:58 hosts
# 在nfs服务端创建一个文件,取个名字叫f1.txt
[root@localhost ftproot]# cp /etc/issue /data/wordpress/f1.txt
# 备份这边可以看到周期时间,一般整分钟,就会多出来一个文件,把文件拷过去,同步成功了
Every 0.5s: ls -l /data/wordpress-backup hu Mar 11 22:20:08 2021
总用量 12
-rw-r--r--. 1 root root 23 3月 11 22:19 f1.txt
-rw-r--r--. 1 root root 541 3月 11 21:58 fstab
-rw-r--r--. 1 root root 158 3月 11 21:58 hosts
# nfs服务端,整个大文件测试一下,创建一个G的大文件
[root@localhost ftproot]# dd if=/dev/zero of=/data/wordpress//f2.img bs=1M count=1024
记录了1024+0 的读入
记录了1024+0 的写出
1073741824字节(1.1 GB)已复制,1.03329 秒,1.0 GB/秒
# 可以看到f2.img一个G的大文件同步过来了,这个一个G如果网络不好,同步是需要花时间的(注意:这个同步有一个问题,我们加文件可以同步过去,但是我们移出文件他就不能同步过去了,我们期望的是nfs这边删除,同步那边也删除是吧,要想同步在计划任务里就不能这么写了,删除也同步是不是计划任务里,要加一个参数,叫--delete选项)
Every 0.5s: ls -l /data/wordpress-backup Thu Mar 11 22:24:27 2021
总用量 1048588
-rw-r--r--. 1 root root 23 3月 11 22:19 f1.txt
-rw-r--r--. 1 root root 1073741824 3月 11 22:23 f2.img
-rw-r--r--. 1 root root 541 3月 11 21:58 fstab
-rw-r--r--. 1 root root 158 3月 11 21:58 hosts
# 修改计划任务,删除也同步
[root@localhost ~]# crontab -e
* * * * * /usr/bin/rsync -a --delete 172.26.119.40:/data/wordpress/ /data/wordpress-backup
# 测试一下,删除一个文件
[root@localhost wordpress-backup]# rm -rf f2.img
# 可以看到,这边已经同步,f2.img 文件没有了,一致了(注意:但是这个周期性的计划任务的话虽然也可以,但是如果一天同步一次的话,可以会导致一天数据的丢失,因为你一天都没做备份了,万一快到一天,快备份的时候,那边挂了一个,挂了你这边是不是还没来得及备份,就丢了一天的数据,那如果一天的数据你觉得也无所谓,那就用这个就可以了,但是企业里一般是不是不愿意丢数据,是吧,这是定时同步。 那如果想让数据少丢失,那就是实时同步,这边一有变化那边马上就变,实时同步有个问题,我们服务器是不是数据变了就要同步不变需要同步吗?不需要吧,但是问题是我怎么知道这个文件变了呢,比如文件改了内容,改了属性,这都算变,变得话我是不是才触发这个同步,没变是不是就没有必要同步,这就是我们要学的inotify)
Every 0.5s: ls -l /data/wordpress-backup Thu Mar 11 22:31:27 2021
总用量 12
-rw-r--r--. 1 root root 23 3月 11 22:19 f1.txt
-rw-r--r--. 1 root root 541 3月 11 21:58 fstab
-rw-r--r--. 1 root root 158 3月 11 21:58 hosts
5.2实现inotify
示例:
[root@localhost ~]
[root@localhost ~]
[root@localhost ~]
Setting up watches.
Watches established.
[root@localhost ~]
[root@localhost ~]
Setting up watches.
Watches established.
/data/wordpress/ CREATE a.txt
[root@localhost ~]
[root@localhost ~]
[root@localhost ~]
/data/wordpress/ CREATE b.txt
/data/wordpress/ OPEN b.txt
/data/wordpress/ ATTRIB b.txt
/data/wordpress/ CLOSE_WRITE,CLOSE b.txt
/data/wordpress/ ATTRIB,ISDIR
/data/wordpress/ OPEN,ISDIR
/data/wordpress/ CLOSE_NOWRITE,CLOSE,ISDIR
/data/wordpress/ DELETE b.txt
/data/wordpress/ ATTRIB,ISDIR
[root@localhost ~]
[root@localhost ~]
PID TTY TIME CMD
1665 pts/0 00:00:00 bash
26761 pts/0 00:00:00 inotifywait
26953 pts/0 00:00:00 ps
[root@localhost ~]
[root@localhost ~]
[root@localhost ~]
2021-03-11 23:54:1615478072 /data/wordpress/abc.txt event: CREATE
2021-03-11 23:54:1615478072 /data/wordpress/abc.txt event: OPEN
2021-03-11 23:54:1615478072 /data/wordpress/abc.txt event: ATTRIB
2021-03-11 23:54:1615478072 /data/wordpress/abc.txt event: CLOSE_WRITE,CLOSE
2021-03-11 23:54:1615478072 /data/wordpress/abc.txt event: CREATE
2021-03-11 23:54:1615478072 /data/wordpress/abc.txt event: OPEN
2021-03-11 23:54:1615478072 /data/wordpress/abc.txt event: ATTRIB
2021-03-11 23:54:1615478072 /data/wordpress/abc.txt event: CLOSE_WRITE,CLOSE
2021-03-11 23:54:1615478072 /data/wordpress/abc.txt event: CREATE
2021-03-11 23:54:1615478072 /data/wordpress/abc.txt event: OPEN
2021-03-11 23:54:1615478072 /data/wordpress/abc.txt event: ATTRIB
2021-03-11 23:54:1615478072 /data/wordpress/abc.txt event: CLOSE_WRITE,CLOSE
创建一个文件测试一下
[root@localhost ~]
2021-03-12 00:03:1615478581 /data/wordpress/abd.txt event:CREATE
2021-03-12 00:03:1615478581 /data/wordpress/abd.txt event:ATTRIB
2021-03-12 00:03:1615478581 /data/wordpress/abd.txt event:CLOSE_WRITE:CLOSE
5.2.1内核支持
内核是否支持inotify (这是内核的一个功能,文件属性的变化,这是属于文件系统的范凑是吧,谁有这个文件系统的管理功能,当然是内核了,所以inotify他是内核的一个功能,inotify就是通知的意思,他的意思就是内核里面帮你监控磁盘文件的属性,一旦发生变化,他给你发消息)
Linux支持inotify的内核最小版本为2.6 .13 ,参看man 7 inotify
[root@centos8 ~]
-rw-r--r--1 root root o Dec 7 10:10 max_queued_events
-rw-r--r--1 root root 0 Dec 7 10:10 max_user_instances
-rw-r--r--1 root root 0 Dec 6 05:54 max_user_watches
[root@centos8 ~]
16384
[root@centos8 ~]
128
[root@centos8 ~]
8192
inotify内核参数说明:
maxqueued_events: inotify事件队列最大长度,如值太小会出现Event Queue Overflow错误,默认值: 16384,生产环境建议调大,比如:327679 (事件队列就是,我们要用inotify发生时间以后要发出消息,通知用户,那么他发生的事件,有队列长度,有一个最大值,这个值16384不够大,如果你的事件发生特别多,建议把这个值尽量调大)
max_userinstances: 每个用户创建inotify实例最大值,默认值: 128 (inotify是监控的程序,他发送消息给我们,这个监控最多开启几个,这个值可以不用动他,因为并不是很多文件夹都通时监控,往往只是监控特定的几个文件夹,需要同步就行了)
max-user-watches: 可以监视的文件的总数量(inotifywait单进程) ,默认值: 8192,建议调大 (一个文件夹里可能有很多文件,这些文件的属性变了,那么监控能通时监控多少个文件,这个值可以指定,8192可能有点太少了,调个一百万,调大点,如果定义的太小,有的文件他监控不到,那就不合适了)
调整值的范例:
[root@data-centos8 ~]
fs.inotify.max_queued_events=66666
fs.inotify.max_user_watches=100000
[root@centos8 ~]
fs.inotify.max_queued_events = 66666
fs.inotify.max_user_watches = 100000
[root@centos8 ~]
66666
128
100000
inotify-tools参考文档: https://gi thub.com/rvoicilas/inotifv-tools/wiki
安装inotify-tools:基于epel源
[root@data-centos8 ~]
inotify-tools包主要工具:(rpm -ql inotify-tools)
inotifywait: (重点要用的程序)(用来监控文件的信息变化,他可以发现文件的一些操作行为,比如是不是打开文件了,是不是把文件又关了,是不是把文件给删了,是不是给文件改属性了,这他都能发现,默认情况下我们提供了一个inotifywait命令)在被监控的文件或目录上等待特定文件系统事件(open , close , delete 等)发生,常用于实时同步的目录监控
inotifywatch: 收集被监控的文件系统使用的统计数据,指文件系统事件发生的次数统计
inotifywait命令(后面可以跟上你要监控的文件夹,但是他这个监控默认是一次性的,就是监控完了就退出了。)
格式:
inotifywait [ options ] filel [file2 ] [ file3 ] [...]
常用选项:
-m, --moniton 始终保持事件监听
-d, --daemon 以守护进程方式执行,和-m相似,配合-0 使用
-r, --recursive 递归监控目录数据信息变化
-q , --quiet 输出少量事件信息
--exclude <pattern> 指定排除文件或目录,使用扩展的正则表达式匹配的模式实现
--excludei <pattern> 和exclude相似,不区分大小写
-o, --outfile <filex 打印事件到文件中,相当于标准正确输出,注意:使用绝对路径
-s, --syslogoutput 发送错误到sys1og相当于标准错误输出
--timefmt <fmtx 指定时间输出格式
--format <fmt> 指定的输出格式:即实际监控输出内容
-e 指定监听指定的事件,如果省略,表示所有事件都进行监听
inotifywait的-timefmt时间格式
参考man 3 strftime
%Y
%y
%m
%d
%H
%M
%S
范例:
--timefmt "%Y-%m-%d %H:%M:%s"
inotifywait的-format 格式定义
%T
%w
%f
%e
%xe
范例:
--format "%T %w%f event: %;e"
--format '%T %w %f
inotifywait -e选项指定的事件类型
create #文件或目录创建
delete #文件或目录被删除
modify #文件或目录内容被写入
attrib #文件或目录属性改变
close write #文件或目录关闭,在写入模式打开之后关闭的
close_nowrite #文件或目录关闭,在只读模式打开之后关闭的
close #文件或目录关闭,不管读或是写模式
open #文件或目录被打开
Isdin #浏览目录内容
moved_to #文件或目录被移动到监控的目录中
moved_ from #文件或目录从监控的目录中被移动
move #文件或目录不管移动到或是移出监控目录都触发事件
access #文件或目录内容被读取
delete_self #文件或目录被删除, 目录本身被删除
unmount #取消挂载
范例:
-e create, delete, moved_to, close_write, attrib
范例:使用inotifywait
监控一次性事件
inotifywait /data/www
setting up watches.
watches established.
/data/www/ CREATE f1.txt
持续前台监控
inotifywait -mrq /data/www -exclude=".*\.swx|\.swp"
/data/www/ OPEN f1.txt
/data/www/ ACCESS f1.txt
/data/www/ CLOSE_NOWRITE,CLOSE f1.txt
持续后台监控,并记录日志
inotifywait -o /root/inotify.log -drq /data/www --timefmt "%Y-%m-%d %H:%M:%s" --format "%T %w%f event: %e"
持续前台监控特定事件
inotifywait -mrq /data/wordpress/ --timefmt "%F %H:%M:%s" --format "%T %w%f event:%:e" -e create,delete,moved_to,close_write,attrib
5.3 rsync
rsync常用于做为linux系统下的数据镜像备份工具,实现远程同步,支持本地复制,或者与其他SSH,sync 主机同步数据,支持增量备份,配合任务计划, rsync能实现定时或间隔同步,配合inotify或sersync,可以实现触发式的实时数据同步
官方网站: http://rsync.samba.orgl
软件包: rsync, rsync-daemon(CentOS 8) (安装sync-daemon这个包以后他就有下面的文件了)
服务文件: /usr/ib/systemd/system/rsyncd.service
配置文件: /etc/rsyncd.conf
端口: 873/tcp (rsync自己专有的端口,他可以监听在873,默认他只是一个客户端,不运行在服务器模式(客户端和服务端的区别就是rsync是客户端,rsyncd是服务端),要想实现服务器模式,需要创建一个/etc/rsyncd.conf配置文件,并且给他启一个rsyncd.service,这个要想实现我们需要安装一个包rsync-daemon,有了这个以后就可以通过rsync来传输文件,只要我们如果要走的是873端口,传输命令用的协议的写法跟我们以前rsync基于ssh协议不一样的)
5.3.1 rsync命令
我们如果要走的是873 端口,传输命令用的协议的写法跟我们以前rsync基于ssh协议不一样的
rsync格式
#Local :
rsync [OPTION...] SRC... [DEST]
#Access via remote shell:
Pull:
rsync [OPTION...] [USER @]HOST:SRC... [DEST]
Push:
rsync [OPTION...] SRC... [USER @]HOST:DEST
#Access via rsync daemon: (使用rsync协议传输时命令两种写法)
Pull:
rsync [OPTION...] [USER @]HOST::SRC... [DEST]
rsync [OPTION...] rsync:/ / [USER @]HOST[:PORT]/ SRC... [DEST]
Push:
rsync [OPTION...] SRC... [USER @]HOST::DEST
rsync [OPTION...] SRC... rsync:/ / [USER @]HOST[:PORT]/ DEST
The ':' usages connect via remote shell, while '::' & 'rsync://' usages connect to an rsync daemon, and require SRC or DEST to start with a module name.
rsync有三种工作方式:
1 ,本地文件系统上实现同步.命令行语法格式为上述"Local"段的格式.
2 ,本地主机使用远程shell和远程主机通信.命令行语法格式为上述"Access via remote shell段的格式.
3,本地主机通过网络套接字连接远程主机上的rsync daemon,命令行语法格式为上述"Access viarsync daemon"段的格式.
前两者的本质是通过本地或远程shell,而第3种方式则是让远程主机上运行rsyncd服务,使其监听在一个端口上,等待客户端的连接.
常见选项:
-v:显示rsync过程中详细信息。可以使用"- vvvv"获取更详细信息。
-P:显示文件传输的进度信息。(实际上"- P"="
- n
- a
- r
- t
:检查出mtime不同从而导致增量传输无效。
- o
- g
- p
- D :是"--device --specials"选项的组合,即也拷贝设备文件和特殊文件。
- l
- z :传输时进行压缩提高效率
- R
- u
- d
:exclude/ include规则生效之后才执行的。
- b
- e :指定所要使用的远程shell程序,默认为ssh。
- W
范例:两种格式访问 rsync daemon 服务
[root@centos8 ~]
Failed to parse config file: /etc/rsyncd.conf (可以看到它缺失/etc/rsyncd.conf这个文件,解决方案只需要把这个文件创建出来就可以了,这个文件不需要有内容就可以启动)
[root@centos8 ~]
[root@centos8 ~]
[root@centos8 ~]
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 5 [::]:873 [::]:*
[root@localhost ~]
[backup] (表示将来要共享的目录)
path = /data/wordpress-backup/ (自己指定需要备份文件夹,如果没有进行创建)
read only = no (默认是只读的,也就是只能看,改成no可读可写,将来用户的数据就可以往里面写了,但是用户看到的不是/data/wordpress-backup/这个名字,而仅仅是这个backup对外发布的名字,相当于一个共享名)
[root@centos8 ~]
mkdir : created directory '/data/wordpress-backup/'
[root@localhost ~]
abc.txt abd.txt f1.txt f2.img fstab hosts
[root@centos8 ~]
[root@localhost ~]
[root@localhost ~]
[root@centos8 ~]
backup
[root@centos8mini ~]
[root@centos8 ~]
total 4
-rw-r--r-- 1 nobody nobody 58 Mar 12 17:55 networks
------------------------------------------------------以下是PPT
[root@backup-centos8 ~]
Failed to parse config file: /etc/rsyncd.conf
[root@backup-centos8 ~]
[root@backup-centos8 ~]
[root@backup-centos8 ~]
LISTEN 0 5 0.0.0.0:873 0.0.0.0:*
users :(("rsync" ,pid=2921,fd=4))
LISTEN 0 5 [::]:873 [::]:*
users :(("rsync" ,pid=2921,fd=5))
5.3.2 以独立服务方式运行rsync并实现验证功能
范例:以独立服务方式运行 rsync
[root@backup-centos8 ~]
[backup]
path = /data/backup/
read only = no
[root@backup-centos8 ~]
[root@data-centos8 ~]
backup
[root@data-centos8 ~]
backup
[root@data-centos8 ~]
[root@data-centos8 ~]
[root@data-centos8 ~]
[root@data-centos8 ~]
[root@data-server ~]
[root@data-server ~]
5.3.2 以独立服务方式运行rsync并实现验证功能
范例:以独立服务方式运行 rsync
[root@centos8 ~]
[root@centos8 ~]
[root@centos8 ~]
uid = root
gid = root
max connections = 0
ignore errors
exclude = lost+found/
log file = /var/log/rsyncd.log
pid file = /var/run/rsyncd.pid
lock file = /var/run/rsyncd.lock
reverse lookup = no
[backup]
path = /data/wordpress-backup/
comment = backup dir
read only = no
auth users = rsyncuser
secrets file = /etc/rsync.pas
[root@centos8 ~]
[root@centos8 ~]
[root@centos8 ~]
-rw------- 1 root root 17 Mar 12 18:59 /etc/rsync.pas
[root@centos8 ~]
Created symlink /etc/systemd/system/multi-user.target.wants/rsyncd.service → /usr/lib/systemd/system/rsyncd.service.
[root@centos8 ~]
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 5 [::]:873 [::]:*
[root@centos8mini ~]
[root@centos8mini ~]
[root@centos8mini ~]
-rw------- 1 root root 6 Mar 12 19:13 /etc/rsync.pas
[root@centos8mini ~]
backup backup dir
[root@centos8mini ~]
Password:
drwxrwxr-x 22 2021/03/12 17:55:49 .
-rw-r--r-- 58 2021/03/12 17:55:49 networks
[root@centos8mini ~]
drwxrwxr-x 22 2021/03/12 17:55:49 .
-rw-r--r-- 58 2021/03/12 17:55:49 networks
[root@centos8mini ~]
Every 0.5s: ls -l /data/wordpress-backup centos8.magedu.org: Fri Mar 12 19:41:27 2021
total 4
-rw-r--r-- 1 nobody nobody 58 Mar 12 17:55 networks
[root@centos8mini ~]
sending incremental file list
deleting networks
./
sent 47 bytes received 31 bytes 52.00 bytes/sec
total size is 0 speedup is 0.00
Every 0.5s: ls -l /data/wordpress-backup centos8.magedu.org: Fri Mar 12 19:46:59 2021
total 0
------------------------------------------------------以下是PPT
[root@backup-centos8 ~]
[root@centos8 ~]
uid = root
gid = root
max connections = 0
ignore errors
exclude = lost+found/
log file = /var/log/rsyncd.log
pid file = /var/run/rsyncd.pid
lock file = /var/run/rsyncd.lock
reverse lookup = no
[backup]
path = /data/backup/
comment = backup dir
read only = no
auth users = rsyncuser
secrets file = /etc/rsync.pas
[root@backup-centos8 ~]
[root@backup-centos8 ~]
[root@backup-centos8 ~]
[root@backup-centos8 ~]
开机启动
[root@backup-centos8 ~]
[root@data-centos8 ~]
[root@data-centos8 ~]
[root@data-server ~]
backup backup dir
[root@data-server ~]
Password:
[root@data-server ~]
rsync://rsyncuser@rsync服务器IP/backup
[root@data-centos8 ~]
/data/www/ rsyncuser@rsync服务器IP::backup
[root@data-centos8 ~]
rsyncuser@rsync服务器IP::backup /data/www/
5.4 inotify+rsync+shell 脚本实现实时数据同步
按 5.3 搭建好 rsyncd的备份服务器,在数据服务器上创建inotify_rsync.sh脚本
注意: 此脚本执行前先确保两主机初始数据处于同步状态,此脚本实现后续的数据同步
[root@data-centos8 ~]
SRC='/data/wordpress/'
DEST='rsyncuser@10.0.0.8::backup'
rpm -q rsync &> /dev/null || yum -y install rsync
inotifywait -mrq --exclude=".*\.swp" --timefmt '%Y-%m-%d %H:%M:%S' --format '%T %w %f' -e create,delete,moved_to,close_write,attrib ${SRC} |while read DATE TIME DIR FILE;do
FILEPATH=${DIR} ${FILE}
rsync -az --delete --password-file=/etc/rsync.pas $SRC $DEST && echo "At ${TIME} on ${DATE} , file $FILEPATH was backuped up via rsync" >> /var/log/changelist.log
done
[root@data-centos8 ~]
5.5 sersync 实现实时数据同步
5.5.1 sersync 介绍
sersync类似于inotify,同样用于监控,但它克服了inotify的缺点.
inotify最大的不足是会产生重复事件,或者同一个目录下多个文件的操作会产生多个事件,例如,当监控目录中有5 个文件时,删除目录时会产生6 个监控事件,从而导致重复调用rsync命令。另外比如:vim
文件时,inotify会监控到临时文件的事件,但这些事件相对于rsync来说是不应该被监控的
sersync 优点:
sersync是使用c++编写,而且对linux系统文件系统产生的临时文件和重复的文件操作进行过滤,所以在结合rsync同步的时候,节省了运行时耗和网络资源。因此更快。
sersync配置很简单,其中提供了静态编译好的二进制文件和xml配置文件,直接使用即可
sersync使用多线程进行同步,尤其在同步较大文件时,能够保证多个服务器实时保持同步状态
sersync有出错处理机制,通过失败队列对出错的文件重新同步,如果仍旧失败,则按设定时长对同步失败的文件重新同步
sersync不仅可以实现实时同步,另外还自带crontab功能,只需在xml配置文件中开启,即也可以按要求隔一段时间整体同步一次,而无需再额外配置crontab功能
sersync 可以二次开发
sersync项目地址: https://code.google.com/archive/p/sersync/
sersync下载地址: https://code.google.com/archive/p/sersync/downloads
5.5.2 基于rsync daemon 实现 sersync
[root@data-centos8 ~]
gz
[root@data-centos8 ~]
[root@data-centos8 ~]
[root@data-centos8 ~]
/etc/profile.d/sersync.sh
[root@data-centos8 ~]
[root@data-centos8 ~]
confxml.xml sersync2
[root@data-centos8 ~]
[root@data-centos8 ~]
[root@data-centos8 ~]
<?xml version="1.0" encoding="ISO-8859-1" ?>
<head version="2.5" >
<host hostip="localhost" port="8008" ></host>
<debug start="false" />
<fileSystem xfs="false" />
<filter start="false" >
步
<exclude expression="(.*)\.svn" ></exclude>
<exclude expression="(.*)\.gz" ></exclude>
<exclude expression="^info/*" ></exclude>
<exclude expression="^static/*" ></exclude>
</filter>
<inotify>
delete/close_write/moved_from/moved_to/create folder
<delete start="true" />
<createFolder start="true" />
<createFile start="false" />
<closeWrite start="true" />
<moveFrom start="true" />
<moveTo start="true" />
<attrib start="true" />
<modify start="false" />
</inotify>
<sersync>
<localpath watch="/data/www" >
目录
<remote ip="备份服务器IP" name="backup" />
daemon的模块名,如果下面开启了ssh start,此时name为远程shell方式运行时的目标目录
<!--<remote ip="192.168.8.39" name="tongbu" />-->
<!--<remote ip="192.168.8.40" name="tongbu" />-->
</localpath>
<rsync>
<commonParams params="-artuz" />
<auth start="true" users ="rsyncuser" passwordfile="/etc/rsync.pas" />
改此行为true ,指定备份服务器的rsync配置的用户和密码文件
<userDefinedPort start="false" port="874" /><!-- port=874 -->
非标准端口号
<timeout start="false" time="100" /><!-- timeout =100 -->
<ssh start="false" />
</rsync>
<failLog path="/tmp/rsync_fail_log.sh" timeToExecute="60" /><!--default every
60mins execute once-->
<crontab start="false" schedule="600" ><!--600mins-->
<crontabfilter start="false" >
<exclude expression="*.php" ></exclude>
<exclude expression="info/*" ></exclude>
</crontabfilter>
</crontab>
<plugin start="false" name="command" />
</sersync>
<plugin name="command" >
<param prefix="/bin/sh" suffix="" ignoreError="true" /> <!--prefix
/opt/tongbu/mmm.sh suffix-->
<filter start="false" >
<include expression="(.*)\.php" />
<include expression="(.*)\.sh" />
</filter>
</plugin>
<plugin name="socket" >
<localpath watch="/opt/tongbu" >
<deshost ip="192.168.138.20" port="8009" />
</localpath>
</plugin>
<plugin name="refreshCDN" >
<localpath watch="/data0/htdocs/cms.xoyo.com/site/" >
<cdninfo domainname="ccms.chinacache.com" port="80" username="xxxx"
passwd="xxxx" />
<sendurl base="http://pic.xoyo.com/cms" />
<regexurl regex="false" match="cms.xoyo.com/site([/a-zA-Z0-
9]*).xoyo.com/images" />
</localpath>
</plugin>
</head>
[root@data-centos8 ~]
[root@data-centos8 ~]
[root@data-centos8 ~]
set the system param
execute:echo 50000000 > /proc/sys/fs/inotify/max_user_watches
execute:echo 327679 > /proc/sys/fs/inotify/max_queued_events
parse the command param
_______________________________________________________
参数-d:启用守护进程模式
参数-r:在监控前,将监控目录与远程主机用rsync命令推送一遍
c参数-n: 指定开启守护线程的数量,默认为10个
参数-o:指定配置文件,默认使用当前工作目录下的confxml.xml文件
参数-m:单独启用其他模块,使用 -m refreshCDN 开启刷新CDN模块
参数-m:单独启用其他模块,使用 -m socket 开启socket模块
参数-m:单独启用其他模块,使用 -m http 开启http模块
不加-m参数,则默认执行同步程序
[root@data-centos8 ~]
set the system param
execute:echo 50000000 > /proc/sys/fs/inotify/max_user_watches
execute:echo 327679 > /proc/sys/fs/inotify/max_queued_events
parse the command param
option: -d run as a daemon
option: -r rsync all the local files to the remote servers before the sersync
work
option: -o config xml name: /usr/local/sersync/confxml.xml
daemon thread num: 10
parse xml config file
host ip : localhost host port: 8008
daemon start,sersync run behind the console
use rsync password-file :
user is rsyncuser
passwordfile is /etc/rsync.pas
config xml parse success
please set /etc/rsyncd.conf max connections=0 Manually
sersync working thread 12 = 1(primary thread) + 1(fail retry thread) +
10(daemon sub threads)
Max threads numbers is: 22 = 12(Thread pool nums) + 10(Sub threads)
please according your cpu ,use -n param to adjust the cpu rate
------------------------------------------
rsync the directory recursivly to the remote servers once
working please wait ...
[root@data-centos8 ~]
rsyncuser@backup-server::backup --password-file=/etc/rsync.pas >/dev/null 2>&1
run the sersync:
watch path is: /data/www
________________________________________________________________
置文件运行
[root@data-centos8 ~]
5.5.3 基于远程shell 实现 sersync
[root@data-centos8 ~]
[root@data-centos8 ~]
[root@data-centos8 ~]
<?xml version="1.0" encoding="ISO-8859-1" ?>
<head version="2.5" >
<host hostip="localhost" port="8008" ></host>
<debug start="false" />
<fileSystem xfs="false" />
<filter start="false" >
<exclude expression="(.*)\.svn" ></exclude>
<exclude expression="(.*)\.gz" ></exclude>
<exclude expression="^info/*" ></exclude>
<exclude expression="^static/*" ></exclude>
</filter>
<inotify>
<delete start="true" />
<createFolder start="true" />
<createFile start="false" />
<closeWrite start="true" />
<moveFrom start="true" />
<moveTo start="true" />
<attrib start="true" />
<modify start="false" />
</inotify>
<sersync>
<localpath watch="/data/www" >
<remote ip="备份服务器IP" name="/data/backup" />
份目标目录
<!--<remote ip="192.168.8.39" name="tongbu" />-->
<!--<remote ip="192.168.8.40" name="tongbu" />-->
</localpath>
<rsync>
<commonParams params="-artuz" />
<auth start="false" users ="root" passwordfile="/etc/rsync.pas" />
改此行,不启用认证
<userDefinedPort start="false" port="874" /><!-- port=874 -->
<timeout start="false" time="100" /><!-- timeout =100 -->
<ssh start="true" />
标主机上配置启动rsync daemon服务
</rsync>
<failLog path="/tmp/rsync_fail_log.sh" timeToExecute="60" /><!--default every
60mins execute once-->
<crontab start="false" schedule="600" ><!--600mins-->
<crontabfilter start="false" >
<exclude expression="*.php" ></exclude>
<exclude expression="info/*" ></exclude>
</crontabfilter>
</crontab>
<plugin start="false" name="command" />
</sersync>
</head>
[root@data-centos8 ~]
set the system param
execute:echo 50000000 > /proc/sys/fs/inotify/max_user_watches
execute:echo 327679 > /proc/sys/fs/inotify/max_queued_events
parse the command param
option: -d run as a daemon
option: -r rsync all the local files to the remote servers before the sersync
work
option: -o config xml name: /apps/sersync/confxml.xml
daemon thread num: 10
parse xml config file
host ip : localhost host port: 8008
daemon start,sersync run behind the console
config xml parse success
please set /etc/rsyncd.conf max connections=0 Manually
sersync working thread 12 = 1(primary thread) + 1(fail retry thread) +
10(daemon sub threads)
Max threads numbers is: 22 = 12(Thread pool nums) + 10(Sub threads)
please according your cpu ,use -n param to adjust the cpu rate
------------------------------------------
rsync the directory recursivly to the remote servers once
working please wait ...
execute command : cd /data/www && rsync -auz -R --delete ./ -e ssh
10.0.0.18:/data/backup >/dev/null 2>&1
run the sersync:
watch path is: /data/www
5.6 实战案例:实现基于分布式的LAMP架构,并将NFS实时同步到备份服务器
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 解答了困扰我五年的技术问题
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 用 C# 插值字符串处理器写一个 sscanf
· Java 中堆内存和栈内存上的数据分布和特点
· 开发中对象命名的一点思考
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· DeepSeek 解答了困扰我五年的技术问题。时代确实变了!
· 本地部署DeepSeek后,没有好看的交互界面怎么行!
· 趁着过年的时候手搓了一个低代码框架
· 推荐一个DeepSeek 大模型的免费 API 项目!兼容OpenAI接口!