https://www.cnblogs.com/tiandi/p/13883306.html
https://www.cnblogs.com/acmilan/p/4217121.html
https://blog.csdn.net/m0_54281425/article/details/124478023
all.css
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
body {
font-family: Tahoma, Times New Roman, Times, serif;
font-size: 13px;
background-color: #E8E8E8;
}
table {
border: 0px;
font-size: 12.99px;
border-collapse:collapse;
margin-bottom: 10px;
margin-top: 10px;
}
th {
padding-left: 1px;
padding-right: 1px;
border: 1px solid #B9B9B9;
height: 28px;
min-width: 55px;
}
td {
padding-left: 3px;
padding-right: 5px;
white-space: nowrap;
border: 1px solid #B9B9B9;
height: 28px;
min-width: 10px;
}
child2.css
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
thead, thead tr th {
position: sticky;
z-index: 2;
top: 0;
background-clip: padding-box;
background-color: #E8E8E8;
outline-color: #B9B9B9;
outline-style: solid;
outline-width: thin;
}
@-moz-document url-prefix(){
thead, thead tr th {
border: none;
}
}
th:nth-child(2) {
position: sticky;
z-index: 3;
left: 0;
background-clip: padding-box;
background-color: #E8E8E8;
}
td:nth-child(2) {
position: sticky;
z-index: 1;
left: 0;
background-clip: padding-box;
background-color: #E8E8E8;
}
table
1
2
3
4
5
6
7
8
9
10
<table >
<thead>
<tr>
<th></th>
</tr>
</thead>
<tr>
</tr>
</table>
需要用到的2个属性
1
2
table-layout : fixed
position : sticky
table-layout
table-layout属性有两种特定值:
auto(预设值)-表格的总宽度决定每一个储存格(cell)的最大值
fixed - 表格的总宽度决定于表格width的定义,以及各栏位(column)width的定义
为了让表格呈现滚动效果,必须设定table-layout:fixed 并且给与表格宽度。
1
2
3
4
table {
table-layout: fixed;
width: 100%;
}
Position
大家对position 的作用应该不陌生,而固定表格则需要使用到 position : sticky 的设定
sticky 的表现类似于relative 和fixed 的合体,在目标区域中可见时,他的行为就像relative 不会有任何变化,而当页面滚动超出目标区域时,他的表现改为fixed会固定于目标位置
要注意的是当position : sticky应用于table,只能作用于
和 ,并且一定要定义目标位置 left / right / top / bottom 才会出现固定效果!
1
2
3
4
thead tr th {
position:sticky;
top:0;
}
https://www.jb51.net/article/213413.htm
后续尝试了 alert() 和 prompt() 这两个跟 confirm 类似的弹对话框函数,情况都与此相同,它们都会跳过页面渲染先被执行。
还有更诡异的情况,我们给某一个 div 里赋值后,立刻 alert 此 div 里的内容,会发现 alert 显示正确的内容,而 div 里的内容却没有更新,并且会一直阻塞到我们点击确定。
alert、prompt、confirm 三个函数都类似,接下来我们就用最简单的 alert 来说。
JavaScript 的线程模型
JavaScript 引擎是单线程运行的,浏览器无论在什么时候都只且只有一个线程在运行 JavaScript 程序,初衷是为了减少 DOM 等共享资源的冲突。可是单线程永远会面临着一个问题,那就是某一段代码阻塞会导致后续所有的任务都延迟。又由于 JavaScript 经常需要操作页面 DOM 和发送 HTTP 请求,这些 I/O 操作耗时一般都比较长,一旦阻塞,就会给用户非常差的使用体验。
于是便有了事件循环(event loop)的产生,JavaScript 将一些异步操作或 有I/O 阻塞的操作全都放到一个事件队列,先顺序执行同步 CPU代码,等到 JavaScript 引擎没有同步代码,CPU 空闲下来再读取事件队列的异步事件来依次执行。
这些事件包括:
setTimeout() 设置的异步延迟事件;
DOM 操作相关如布局和绘制事件;
网络 I/O 如 AJAX 请求事件;
用户操作事件,如鼠标点击、键盘敲击。
解决
明白了原理, 再解决这个问题就有了方向,我们来分析这个问题:
1.由于页面渲染是 DOM 操作,会被 JavaScript 引擎放入事件队列;
2.alert() 是 window 的内置函数,被认为是同步 CPU代码;
3.JavaScript 引擎会优先执行同步代码,alert 弹窗先出现;
4.alert 有特殊的阻塞性质,JavaScript 引擎的执行被阻塞住;
5.点击 alert 的“确定”,JavaScript 没有了阻塞,执行完同步代码后,又读取事件队列里的 DOM 操作,页面渲染完成。
由上述原因,导致了诡异的 “alert执行顺序问题”。 我们无法将页面渲染变成同步操作,那么只好把 alert() 变为异步代码,从而才能在页面渲染之后执行。
对于这个解决方向,我们有两种方法可以使用:
setTimeOut函数
setTimeout() 这个函数可以延迟执行某些代码。而对于延迟执行的代码,JavaScript 引擎总是把这些代码放到事件队列里去,再去检查是否已经到了执行时间,再适时执行。代码进入事件队列,就意味着代码变成和页面渲染事件一样异步了。由于事件队列是有序的,我们如果用 setTimeout 延时执行,就可以实现在页面渲染之后执行 alert 的功能了。
setTimeout 的函数原型为 setTimeout(code, msec),code 是要变为异步的代码或函数,msec 是要延时的时间,单位为毫秒。这里我们不需要它延时,只需要它变为异步就行了,所以可以将 msec 设置为 0;
同样,alert 之后的代码我们也需要处理,将它们跟 alert 一块放到 setTimeout 里异步执行。这样,代码就变为 setTimeout(“alert(‘msg’);doSomething();”, 0);,如果觉得代码不够美观或字符串不好处理的话,可以将后续代码封装成一个函数放到 doSomething() 里即可。
替换 Alert() 函数
首先我们考虑替换掉 alert 函数的功能。其实大多数情况下我们替换掉 alert 并不是它不符合我们期待的执行顺序,而是因为它实在是太丑了,而且也不支持各种美化,可以想像在一个某一特定主题的网站上忽然弹出来一个灰色单调的对话框是多么不和谐。
这个我们可以考虑 Bootstrap 的 modal 模块,Bootstrap 在绝大多数网站上都在应用,而多引入一个 modal 模块也不会有多大影响。我们使用 modal 构造一个弹出对话框的样子,使用 modal 的 modal(‘toggle’)/modal(‘show’)/modal(‘hide’) 方法可以很方便地控制 modal 的显隐。
替换掉对话框后,我们还需要解决后续代码执行的问题。使用 alert 函数时,我们点击确定后代码还会继续执行,而使用我们自定义的对话框可没有这种功能了,需要考虑把后续代码绑定在对话框的点击按钮上,这就需要使用 DOM 的 onclick 属性了,我们将后续函数内容抽出一个新的函数,在弹出对话框后将这个函数绑定在按钮的 onclick 事件上即可。
这里还需要注意,新函数内应该包括关闭 modal 对话框的内容。
当然,我们还可以再优化一下,抽象出来一个用来弹出对话框的函数替代 alert 函数,示例如下:
1
2
3
4
5
6
7
8
window.alert = function (message, callbackFunc) {
$('#alertContent').html(message);
$('#modal').show();
$('#confirmButton').onclick(function () {
$('#modal').hide();
callbackFunc();
});
};
如此,我们在需要弹出框时调用新的 alert 函数,并传入 callbackFunc ,在里面做后续的事情就可以了。
小结
在上面的两个解决方案中,都利用了 JavaScript 的回调函数,前者将函数所为 alert 的参数并绑定到 DOM 的 onclick 事件,后者使用 setTimeout 将函数转为异步执行。
原始
1
2
3
4
5
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
167.94.146.58 - - [09/Nov/2022:05:05:14 +0800] "GET /images/splash/splash-icon.png HTTP/1.1" 404 1163 "-" "Mozilla/5.0 (compatible; CensysInspect/1.1; +https://about.censys.io/)" "-"
改后
1
2
3
4
log_format main '$time_local $server_addr $server_port $remote_addr $remote_port $status $body_bytes_sent - $remote_user '
'"$host" "$request" "$http_referer" "$http_user_agent" "$http_x_forwarded_for"';
10/Nov/2022:10:32:58 +0800 192.168.100.41 49090 192.168.120.177 65123 404 1163 - - "192.168.100.41" "GET /images/splash/splash-icon.png HTTP/1.1" "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:67.0) Gecko/20100101 Firefox/67.0" "-"
再改后
1
2
3
4
log_format main '$time_local $request_time $server_addr $server_port $remote_addr $remote_port $status $body_bytes_sent $request_method $server_protocol'
' "$host" "$uri" "$query_string" "$http_referer" "$http_user_agent" "$http_x_forwarded_for" - $remote_user';
20/Nov/2022:13:19:17 +0800 0.001 192.168.100.41 49090 183.136.225.45 58722 404 1163 GET HTTP/1.1 "np.cn" "/favicon.ico" "-" "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36 QIHU 360SE" "-" - -
再改时间格式、ssl
1
2
3
4
5
6
7
8
9
10
11
12
13
log_format main '$fmt_localtime $request_time $server_addr $server_port $remote_addr $remote_port $status $body_bytes_sent $request_method $server_protocol'
' "$host" "$uri" "$query_string" "$http_referer" "$http_user_agent" "$ssl_protocol" "$ssl_cipher" "-" "$remote_user" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
map $host $fmt_localtime {
default '';
}
log_by_lua_block {
ngx.var.fmt_localtime = ngx.localtime();
}
2022-11-25 17:15:07 0.046 192.168.100.141 17883 223.104.49.27 12492 200 3371 GET HTTP/1.1 "www.np.cn" "/login" "-" "-" "Mozilla/5.0 (Android 7.0; Mobile; rv:104.0) Gecko/104.0 Firefox/104.0" "TLSv1.2" "ECDHE-RSA-AES128-GCM-SHA256" "-" "-" "-"
https://www.cnblogs.com/funcquery/p/16026830.html
https://www.88ksk.cn/blog/145.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
$remote_addr:记录访问网站的客户端地址
$remote_user:远程客户端用户名称
$time_local:记录访问时间与时区
$request:表示request请求头的行
$status:http状态码,记录请求返回的状态,例如:200、404、301等
$body_bytes_sent:服务器发送给客户端的响应body字节数
$http_referer:记录此次请求是从哪个链接访问过来的,可以根据refer进行防盗链设置
$http_user_agent:记录客户端访问信息,例如:浏览器,手机客户端等
$http_x_forwarded_for:当前端有代理服务器时,设置Web节点记录客户端地址的配置,此参数生效的前提是代理服务器上也进行了相关的http_x_forwarded_for设置
$ssl_protocol:SSL协议版本
$ssl_cipher:交换数据中的算法
$upstream_status:upstream状态
$upstream_addr:当ngnix做负载均衡时,可以查看后台提供真实服务的设备
$upstream_response_time:请求过程中,upstream响应时间
$request_time:整个请求的总时间
$args:这个变量等于请求行中的参数,同$query_string
$content_length:请求头中的Content-length字段。
$content_type:请求头中的Content-Type字段。
$document_root:当前请求在root指令中指定的值。
$host:请求主机头字段,否则为服务器名称。
$http_user_agent:客户端agent信息
$http_cookie:客户端cookie信息
$limit_rate:这个变量可以限制连接速率。
$request_method:客户端请求的动作,通常为GET或POST。
$remote_addr:客户端的IP地址。
$remote_port:客户端的端口。
$remote_user:已经经过Auth Basic Module验证的用户名。
$request_filename:当前请求的文件路径,由root或alias指令与URI请求生成。
$scheme:HTTP方法(如http,https)。
$server_protocol:请求使用的协议,通常是HTTP/1.0或HTTP/1.1。
$server_addr:服务器地址,在完成一次系统调用后可以确定这个值。
$server_name:服务器名称。
$server_port:请求到达服务器的端口号。
$request_uri:包含请求参数的原始URI,不包含主机名,如:”/foo/bar.php?arg=baz”。
$uri:不带请求参数的当前URI,$uri不包含主机名,如”/foo/bar.html”。
$document_uri:与$uri相同。
https://www.cnblogs.com/gengjian/p/15749636.html
什么是NFS?
NFS 是 Network File System 的缩写及网络文件系统。 NFS 主要功能是通过局域网络让不同的主机系统之间可以共享文件或目录。
NFS 系统和 Windows 网络共享、网络驱动器类似, 只不过 windows 用于局域网, NFS 用于企业集群架构中, 如果是大型网站, 会用到更复杂的分布式文件系统FastDFS,glusterfs,HDFS
NFS工作原理
1.用户进程访问 NFS 客户端,使用不同的函数对数据进行处理
2.NFS 客户端通过 TCP/IP 的方式传递给 NFS 服务端
3.NFS 服务端接收到请求后,会先调用 portmap 进程进行端口映射。
4.nfsd 进程用于判断 NFS 客户端是否拥有权限连接 NFS 服务端。
5.Rpc.mount 进程判断客户端是否有对应的权限进行验证。
6.idmap 进程实现用户映射和压缩
7.最后 NFS 服务端会将对应请求的函数转换为本地能识别的命令,传递至内核,由内核驱动硬件。
注意: rpc 是一个远程过程调用,那么使用 nfs 必须有 rpc 服务
1.3 前提条件
1.nfs依赖于RPC服务来传递消息
2.NFS服务启动的端口号是随机的,启动之后会向本地的RCP注册
3.先启动RPC服务,再启动NFS服务
4.NFS和RPC之间的通讯是他们自己内部完成的,对于用户来说无感知
5.NFS客户端和服务端不会直接沟通,必须通过RPC服务传递消息
6.防火墙要开放RPC服务的端口
二、NFS服务端部署实践
2.1 安装nfs
1
yum install nfs-utils -y
2.2 配置参数
1
nfs 服务程序的配置文件为/etc/exports,需要严格按照共享目录的路径 允许访问的 NFS 客户端(共享权限参数)格式书写,定义要共享的目录与相应的权限,具体书写方式如下图所示
配置文件参数解释:
执行 man exports 命令,然后切换到文件结尾,可以快速查看如下样例格式:
nfs共享参数
参数作用
rw
读写权限 (常用)
ro
只读权限 (不常用)
root_squash
当NFS客户端以root管理员访问时,映射为NFS服务器的匿名用户 (不常用)
no_root_squash
当NFS客户端以root管理员访问时,映射为NFS服务器的root管理员 (不常用)
all_squash
无论NFS客户端使用什么账户访问,均映射为NFS服务器的匿名用户 (常用)
no_all_squash
无论NFS客户端使用什么账户访问,都不进行压缩 (不常用)
sync
同时将数据写入到内存与硬盘中,保证不丢失数据 (常用)
async
优先将数据保存到内存,然后再写入硬盘;这样效率更高,但可能会丢失数据 (不常用)
anonuid
配置all_squash使用,指定NFS的用户UID,必须存在系统 (常用)
anongid
配置all_squash使用,指定NFS的用户GID,必须存在系统 (常用)
2.3 配置NFS服务端
写入配置文件:注意!IP地址和后面的小括号没有空格
1
2
3
[root@nfs01 ~]# cat > /etc/exports <<EOF
/data 172.16.1.0/24(rw,sync,all_squash)
EOF
创建数据目录和授权:
1
2
[root@nfs01 ~]# mkdir /data -p
[root@nfs01 ~]# chown -R nfsnobody:nfsnobody /data/
2.4 启动nfs
1
[root@nfs01 ~]# systemctl start nfs-server.service
2.5 检查命令
1
2
3
[root@nfs01 ~]# showmount -e 172.16.1.31
Export list for 172.16.1.31:
/data 172.16.1.0/24
2.6 加入开机自启动
在使用 NFS 服务进行文件共享之前,需要使用 RPC(Remote Procedure Call 远程过程调用服务将 NFS 服务器的IP 地址和端口号信息发送给客户端。因此,在启动 NFS 服务之前,需要先重启并启用 rpcbind 服务程序,同时都加入开机自启动
1
2
[root@nfs01 ~]# systemctl enable rpcbind nfs-server
[root@nfs01 ~]# systemctl restart rpcbind nfs-server
2.7 客户端挂载命令
客户端安装nfs服务十分简单,只需要安装nfs软件包即可
1
[root@backup ~]# yum install nfs-utils rpcbind -y
安装完成后只需要启动rpcbind,不需要启动nfs
1
[root@backup ~]# systemctl restart rpcbind
使用showmount命令查看nfs共享信息查询 NFS 服务器的远程共享信息,其输出格式为“共享的目录名称 允许使用客户端地址”。
1
2
3
[root@backup ~]# showmount -e 172.16.1.31
Export list for 172.16.1.31:
/data 172.16.1.0/24
挂载命令: 创建挂载目录
在 NFS 客户端创建一个挂载目录, 使用 mount 命令并结合-t 参数, 指定要挂载的文件系统的类型, 并在命令后面写上服务器的 IP 地址, 以及服务器上的共享目录, 最后需要写上要挂载到本地系统(客户端)的目录
1
2
[root@backup ~]# mkdir /data -p
[root@backup ~]# mount -t nfs 172.16.1.31:/data /data
查看是否挂载成功:
1
2
3
4
5
6
7
8
9
10
[root@backup ~]# df -h
文件系统 容量 已用 可用 已用% 挂载点
/dev/sda3 18G 1.9G 17G 11% /
devtmpfs 480M 0 480M 0% /dev
tmpfs 489M 0 489M 0% /dev/shm
tmpfs 489M 32M 458M 7% /run
tmpfs 489M 0 489M 0% /sys/fs/cgroup
/dev/sda1 1014M 110M 905M 11% /boot
tmpfs 98M 0 98M 0% /run/user/0
172.16.1.31:/data 18G 1.9G 17G 11% /data
测试写入数据是否正常
1
2
3
[root@backup ~]# echo "111" > /data/111.txt
[root@backup ~]# cat /data/111.txt
oldzhang
写入开机自动挂载
1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@backup ~]# vim /etc/fstab
[root@backup ~]# tail -1 /etc/fstab
172.16.1.31:/data /data nfs defaults 0 0
[root@backup ~]# mount -a
[root@backup ~]# df -h
文件系统 容量 已用 可用 已用% 挂载点
/dev/sda3 18G 1.9G 17G 11% /
devtmpfs 480M 0 480M 0% /dev
tmpfs 489M 0 489M 0% /dev/shm
tmpfs 489M 32M 458M 7% /run
tmpfs 489M 0 489M 0% /sys/fs/cgroup
/dev/sda1 1014M 110M 905M 11% /boot
tmpfs 98M 0 98M 0% /run/user/0
172.16.1.31:/data 18G 1.9G 17G 11% /data
卸载命令:注意!卸载的时候如果提示”umount.nfs: /nfsdir: device is busy”先切换到其他目录再卸载
1
[root@backup ~]# umount /data/
强制卸载命令:
1
[root@backup ~]# umount -rl /data/
2.8 NFS 权限验证
2.8.1 验证ro权限
服务端配置:
1
2
3
4
5
6
[root@nfs01 ~]# cat /etc/exports
/data 172.16.1.0/24(ro,sync,all_squash)
[root@nfs01 ~]# systemctl restart nfs-server.service
[root@nfs01 ~]# showmount -e 172.16.1.31
Export list for 172.16.1.31:
/data 172.16.1.0/24
客户端挂载:
1
2
3
4
5
6
7
8
9
10
11
[root@backup ~]# mount -t nfs 172.16.1.31:/data /data
[root@backup ~]# df -h
文件系统 容量 已用 可用 已用% 挂载点
/dev/sda3 18G 1.9G 17G 11% /
devtmpfs 480M 0 480M 0% /dev
tmpfs 489M 0 489M 0% /dev/shm
tmpfs 489M 38M 452M 8% /run
tmpfs 489M 0 489M 0% /sys/fs/cgroup
/dev/sda1 1014M 110M 905M 11% /boot
tmpfs 98M 0 98M 0% /run/user/0
172.16.1.31:/data 18G 1.9G 17G 11% /data
测试读取:
1
2
[root@backup ~]# cat /data/111.txt
111
写入测试:
1
2
[root@backup ~]# echo "backup" > /data/111.txt
-bash: /data/111.txt: 权限不够
2.8.2 验证all_squash、 anonuid、 anongid 权限
服务端配置:
1
2
[root@nfs01 ~]# cat /etc/exports
/data 172.16.1.0/24(rw,sync,all_squash,anonuid=666,anongid=666)
服务端创建用户及授权:
1
2
3
[root@nfs01 ~]# useradd -s /sbin/nologin -M -u 666 -g 666 www
[root@nfs01 ~]# id www
uid=666(www) gid=666(www) 组=666(www)
重启NFS服务:
1
[root@nfs01 ~]# systemctl restart nfs-server.service
更改目录授权:
1
2
3
[root@nfs01 ~]# chown -R www:www /data/
[root@nfs01 ~]# ls -ld /data/
drwxr-xr-x 2 www www 35 7月 17 19:50 /data/
客户端操作:
1
2
3
4
5
6
7
8
9
10
[root@backup ~]# mount -t nfs 172.16.1.31:/data /data
[root@backup ~]# ls -ld /data/
drwxr-xr-x 2 666 666 35 7月 17 19:50 /data/
[root@backup ~]# ll /data/
总用量 4
-rw-r--r-- 1 666 666 0 7月 17 19:50 123
-rw-r--r-- 1 666 666 9 7月 17 19:46 111.txt
[root@backup ~]# echo "111" > /data/111.txt
[root@backup ~]# cat /data/111.txt
oldzhangy
我们会发现依然可以写入,但是为了避免这种情况发生,建议客户端也创建相同uid gid的用户
1
2
3
4
5
6
7
8
9
10
[root@backup ~]# groupadd -g 666 www
[root@backup ~]# useradd -s /sbin/nologin -M -u 666 -g 666 www
[root@backup ~]# id www
uid=666(www) gid=666(www) 组=666(www)
[root@backup ~]# ls -ld /data/
drwxr-xr-x 2 www www 35 7月 17 19:50 /data/
[root@backup ~]# ll /data/
总用量 4
-rw-r--r-- 1 www www 0 7月 17 19:50 123
-rw-r--r-- 1 www www 10 7月 17 21:31 111.txt
查看nfs端口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[root@nfs01 ~]# rpcinfo -p
program vers proto port service
100000 4 tcp 111 portmapper
100000 3 tcp 111 portmapper
100000 2 tcp 111 portmapper
100000 4 udp 111 portmapper
100000 3 udp 111 portmapper
100000 2 udp 111 portmapper
100024 1 udp 43177 status
100024 1 tcp 36750 status
100003 3 tcp 2049 nfs
100003 4 tcp 2049 nfs
100227 3 tcp 2049 nfs_acl
100003 3 udp 2049 nfs
100003 4 udp 2049 nfs
100227 3 udp 2049 nfs_acl
100021 1 udp 41388 nlockmgr
100021 3 udp 41388 nlockmgr
100021 4 udp 41388 nlockmgr
100021 1 tcp 43678 nlockmgr
100021 3 tcp 43678 nlockmgr
100021 4 tcp 43678 nlockmgr```
firewall防火墙配置
1
2
3
4
firewall-cmd --add-service=nfs --permanent
firewall-cmd --add-service=mountd --permanent
firewall-cmd --add-service=rpc-bind --permanent
firewall-cmd --reload
iptables防火墙配置
启动NFS会开启如下端口:
1
2
3
4
1)portmapper 端口:111 udp/tcp;
2)nfs/nfs_acl 端口:2049 udp/tcp;
3)mountd 端口:"32768--65535" udp/tcp
4)nlockmgr 端口:"32768--65535" udp/tcp
系统 RPC服务在 nfs服务启动时默认会给 mountd 和 nlockmgr 动态选取一个随机端口来进行通讯。
1.查看NFS启动后的端口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[root@nfs01 /opt/sersync]# rpcinfo -p
program vers proto port service
100000 4 tcp 111 portmapper
100000 3 tcp 111 portmapper
100000 2 tcp 111 portmapper
100000 4 udp 111 portmapper
100000 3 udp 111 portmapper
100000 2 udp 111 portmapper
100024 1 udp 43177 status
100024 1 tcp 36750 status
100003 3 tcp 2049 nfs
100003 4 tcp 2049 nfs
100227 3 tcp 2049 nfs_acl
100003 3 udp 2049 nfs
100003 4 udp 2049 nfs
100227 3 udp 2049 nfs_acl
100021 1 udp 41388 nlockmgr
100021 3 udp 41388 nlockmgr
100021 4 udp 41388 nlockmgr
100021 1 tcp 43678 nlockmgr
100021 3 tcp 43678 nlockmgr
100021 4 tcp 43678 nlockmgr
2.将随机的端口号设置固定
1
2
3
4
5
6
7
[root@nfs01 ~]# vim /etc/sysconfig/nfs
[root@nfs01 ~]# tail -5 /etc/sysconfig/nfs
RQUOTAD_PORT=4001
LOCKD_TCPPORT=4002
LOCKD_UDPPORT=4002
MOUNTD_PORT=4003
STATD_PORT=4004
3.重启nfs和rpc服务
1
[root@nfs01 ~]# systemctl restart rpcbind.service nfs-server.service
4.再次查看端口信息,发现端口号已经固定了
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
[root@nfs01 ~]# rpcinfo -p
program vers proto port service
100000 4 tcp 111 portmapper
100000 3 tcp 111 portmapper
100000 2 tcp 111 portmapper
100000 4 udp 111 portmapper
100000 3 udp 111 portmapper
100000 2 udp 111 portmapper
100024 1 udp 43177 status
100024 1 tcp 36750 status
100005 1 udp 4003 mountd
100005 1 tcp 4003 mountd
100005 2 udp 4003 mountd
100005 2 tcp 4003 mountd
100005 3 udp 4003 mountd
100005 3 tcp 4003 mountd
100003 3 tcp 2049 nfs
100003 4 tcp 2049 nfs
100227 3 tcp 2049 nfs_acl
100003 3 udp 2049 nfs
100003 4 udp 2049 nfs
100227 3 udp 2049 nfs_acl
100021 1 udp 4002 nlockmgr
100021 3 udp 4002 nlockmgr
100021 4 udp 4002 nlockmgr
100021 1 tcp 4002 nlockmgr
100021 3 tcp 4002 nlockmgr
100021 4 tcp 4002 nlockmgr
https://blog.csdn.net/weixin_52270081/article/details/126379020
https://blog.51cto.com/chenguang/1606746
http://www.adintr.com/article/blog/327
https://www.cnblogs.com/Maker-Liu/p/16591621.html
Samba 配置只能上传下载不能删除修改的方法
让上传的文件不能修改, 只需要让上传的文件的权限里不包含写权限即可.
要让文件不能删除, 则涉及到文件父目录的写权限问题, 但是不能直接关闭父目录的写权限, 因为这样就不能在该目录下上传文件了.
解决方法是在父目录上设置 t 标志位, 这用用户就不能删除这个目录下不属于自己的文件, 所以还需要设置文件的所有者不能是上传的用户, 将其设置为 root 即可.
综上,
1
首先对共享的根目录设置 1777 权限, 所有者为 root, 然后配置文件 /etc/samba/smb.conf 里面的设置:
2
1
2
3
4
5
inherit owner = yes # 上传的文件继承父目录的所有者, 而不是使用登录的账号名, 这样上传的文件的所有者都是 root 了.
writable = yes # 允许上传操作
create mask = 1774 # 上传的文件没有写权限
directory mask = 1777 # 上传的目录具有所有权限
force directory mode = 1000 # 上传的目录设置 t 标志
3
稍作修改, 去掉 inherit owner = yes 即可让用户可以删除自己上传的文件, 不能删除其他用户创建的文件
如何做到将每个客户端的连接信息存放在单独的文件呢?在smb.conf文件中:
1
2
3
log file = /var/log/samba/%m.log
max log size = 5000 最大日志容量为 5000KB
通过log level参数来调整日志记录级别,级别越高,记录越详细。Samba使用LOG_DAEMON将日志级别分为10级,下表1列出常用的4级。
1
2
3
4
5
类型 级别
LOG_ERR 0
LOG_WARNING 1
LOG_NOTICE 2
LOG_INFO 3
配置内核参数
1
2
3
4
5
6
7
8
9
10
11
ulimit -n 16384
vi /etc/security/limits.conf
在最后加入以下内容
* - nofile 16384
tips: 这主要是避免在启动Samba时出现以下警告信息:
rlimit_max: increasing rlimit_max (1024) tominimum Windows limit (16384)
一,samba的基本概念
在早期的网络世界中,文件数据在不同主机之间的传输大多是使用 ftp,但是使用ftp服务传输档案使得我们无法直接修改主机上面的档案数据。NFS服务可以实现在客户端的机器上直接使用服务器上面的文件,但是NFS主要在unix系列操作系统上使用。windows上面也有类似的文件系统,那就是cifs(Common Internet File system,通用internet文件系统),cifs的最简单的用途就是“网上邻居”,但是cifs只能让windows机器沟通。
所以,为了实现windows和unix系列系统之间能够相互沟通,就产生了samba服务。
SMB(Server Messages Block,信息服务块)是一种在局域网上共享文件和打印机的一种通信协议,它为局域网内的不同计算机之间提供文件及打印机等资源的共享服务。
Samba服务:是提供基于Linux和Windows的共享文件服务,服务端和客户端都可以是Linux或Windows操作系统。可以基于特定的用户访问,功能比NFS更强大。
二,samba的安装
1
2
3
yum install samba samba-common
apt-get install samba samba-common
三,samba的基本配置
首先最简单的配置,找到一个文件夹作为共享文件,如:/ubuntu/home/share
1:更改share文件权限,授予所有权限
2:更改配置文件 /etc/samba/smb.conf
最后添加以下内容
1
2
3
4
5
6
7
8
9
10
11
[share]
comment = var www share
path = /var/www/share
public = yes
writable = yes
inherit owner = yes
create mask = 1444
directory mask = 1777
force directory mode = 1000 # 上传的目录设置 t 标志
# valid users = smbtest,smbtest2 用户控制
保存退出,重启samba服务
四,samba的账号权限配置
创建账号及密码
1
useradd -d / -s /sbun/nologin smbtest2
由于Samba用户要以系统用户为基础,因而需要先创建出系统用户之后,再将其添加为Samba用户。
由于不需要这些账号登录服务器权限,所以设置参数 /sbin/nologin。
可以通过执行 pdbedit -L命令列表显示目前系统中已经存在的所有Samba用户。
一台电脑登录多个账号,会报错,
不允许一个用户使用一个以上用户名与一个服务器或共享资源的多重连接。中断与此服务器或共享资源的所有连接,然后再试一次
如果需要其他账号登录,断开原账号解决方法:
可使用以下命令断掉已有连接(开始 -> cmd) 不要超级管理员
五,samba目录设置对指定用户可见
有些情况设定,需要自己账号登录,只可见自己授权的目录,其他目录不可见。
例如:这里 /samba/PM 目录,只对登录pm账号用户可见。
1:global注释掉map to guest = bad user
打开编辑配置文件
在 [global] 下找到 map to guest = bad user,这个参数配置,是实现匿名无须交互输入用户名和密码的,登录IP访问时不需要输入用户名和密码了。